Heat map using openlayers - javascript

I am trying to create a heat map using openlayers.
What i want to do is say i have a custom score function which return some float value, i want to use that value to decide a color for data point.
Higher the value the darker is the color point (more towards red). Lesser the value the lighter the color point (more towards green or blue).
Please can someone suggest how i can achieve this.
My javascript code for heatmap is as below
var vector = new ol.layer.Heatmap({
source: new ol.source.Vector({
url: 'http://localhost:8080/heatmapKML',
format: new ol.format.KML({
extractStyles: false
})
}),
blur: 15,
radius: 5
});
var raster = new ol.layer.Tile({
source: new ol.source.Stamen({
layer: 'toner'
})
});
var map = new ol.Map({
layers: [raster, vector],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 3
})
});
Thanks

open layer heat map has few properties that can be tweaked. Refer open layer api documentation.
The weight property can be set to differentiate the color of a data point.
You can implement a custom score function on javascript side or on backend side and then fetch value in javascript side.
The point is that setting weight for each data point will define the color intensity for it.
So in the above code that i have shared, i just added below line before creating raster variable.
vector.getSource().on('addfeature', function(event) {
var score = event.feature.get('score');
event.feature.set('weight', score);
});
The value for score came from a custom score function defined at the backend.
As you can see the two data points have different color intensity.

Related

Extending LineString/MultiLineString along existing Feature

I have given coordinates of two points. I can draw a LineString that is connecting these two points. What I'd like to achieve is having a LineString/MultiLineString that's connecting points but it's also a little longer (let's say 20% longer than distance between these two points) and it's extended after one point only.
What I currently have:
What I want to achieve:
My issue is that I don't know how to find position of third point which would indicate end of the line. It should be placed exactly along existing line in given distance. Any kind of map projection is not important, because I just want to have a line that will be always straight.
const markerOne = new ol.Feature({
geometry: new ol.geom.Point([-1000, -1000])
});
const markerTwo = new ol.Feature({
geometry: new ol.geom.Point([1000, 1000])
});
const lineStrEnd = ?;
const lineStr = new ol.Feature({
geometry: new ol.geom.LineString([markerOne.getGeometry().getCoordinates(), lineStrEnd])
});
HERE'S WORKING FIDDLE
The simplest way would be to scale the geometry, e.g. a linestring from markerOne to markerTwo increased by 20% with the scaling anchored at markerOne so the line extents beyond markerTwo
const lineStr = new ol.Feature({
geometry: new ol.geom.LineString([markerOne.getGeometry().getCoordinates(), markerTwo.getGeometry().getCoordinates()])
});
lineStr.getGeometry().scale(1.2, 1.2, markerOne.getGeometry().getCoordinates());

Converting OpenLayers Polygon to GeoJSON with different projection

Similar to the problem found in this question
How to convert OpenLayers polygon coordinates into latitude and longitude?
I have setup a basic map to capture a user defined polygon and convert it to GeoJSON, whilst I'm able to do this with its native projection (ESPG:3857) I would like to take the captured GeoJSON and convert it to EPSG:4326 - which I will then save away. Using the above method of capturing the feature on the drawend event and performing a transform however removes the polygon as the new co-ordinates are not represented in the projection of the map any longer. I am unable to figure out how to to save the GeoJSON in the format I need without deleting the existing polygon
I have tried performing this by using getFeatures on the vector source of the polygon and then performing a transform from the projection i'm using to the projection I want, but this still returns the same coords, I have also (like the linked article) tried using the the writeFeatureObject but it still saves incorrectly
https://jsfiddle.net/20gxo3nt/
dragBox.on('drawend', function(evt){
/* geom = evt.feature.getGeometry().transform('EPSG:3857', 'EPSG:4326');
console.log(geom.getCoordinates()); */
});
$( "#save" ).click(function() {
var geom=vectorSource.getFeatures();
console.log(geom);
var writer=new ol.format.GeoJSON();
var geoJsonStr = writer.writeFeatures(geom);
console.log (geom.proj.transform('EPSG:3857', 'EPSG:4326'));
/* console.log(geoJsonStr) */
});
Uncommenting the code on the drawend event will correctly console.log the co-ordinates,as well as demonstrate polygon disappearing
To get a new geojson
var geom = [];
vectorSource.forEachFeature( function(feature) { geom.push(new ol.Feature(feature.getGeometry().clone().transform('EPSG:3857', 'EPSG:4326'))); } );
var writer = new ol.format.GeoJSON();
var geoJsonStr = writer.writeFeatures(geom);
console.log(geoJsonStr);
Openlayers 6, no need to loop on features
var format = new ol.format["GeoJSON"]();
var geoJsonStr = format.writeFeatures(vectorSource.getFeatures(), { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857'});

Remove all points from polygon one by one

I'm creating a feature of removing points from openlayers polygons when drawing. So there is my "configuration":
source = new ol.source.Vector({
wrapX: false,
});
raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
vector = new ol.layer.Vector({
source: source,
style: new ol.style.Style(/* some config */)
});
view = new ol.View({
center: defaultLonLatFormat,
zoom: 12
});
mapx = new ol.Map({
layers: [raster, vector],
target: 'target',
view: view
});
Code used to start drawing:
draw = new ol.interaction.Draw({
source: source,
type: 'Polygon',
});
mapx.addInteraction(draw);
Code used to remove last point:
draw.removeLastPoint();
draw.changed();
Everything works like a charm until polygon is open - until I connect last point with first point. After that removing last point makes nothing. Fortunatelly I can delete points with alt + click - it works until there is 3 points left which makes minimal closed polygon - triangle. Then even alt + click combination doesn't work. I've even tried this on OpenLayers examples - this same behaviour. So I've got three questions:
What happens after closing polygon, so I can't delete points with draw.removeLastPoint()?
Why I'm unable to delete last three points from polygon?
Any ideas how to achieve such functionality?
After the drawing is finished, the sketch is added to the target layer, and also removed from the draw interaction, so if you want to access it, you need to call
source.getFeatures();
any draw interaction functions do no longer have effect on it.
As written here, Polygon is:
Array of linear rings that define the polygon. The first linear ring of the array defines the outer-boundary or surface of the polygon. Each subsequent linear ring defines a hole in the surface of the polygon. A linear ring is an array of vertices' coordinates where the first coordinate and the last are equivalent.
Technically, when the outer boundary is not a linear ring it is not a valid polygon. When you have less than three coordinates, it is more of a line.
You can check the number of points in the polygon geometry and when trying to delete the third point, change the geometry to line (or more preciesly to LineString), and when deleting the second point change it to point.

Creating a food places/restaurant Autocomplete field with multiple bounds using Google Maps JavaScript API

I am attempting to create a food places/restaurants Autocomplete field that does the following:
Prioritizes so food places/restaurants near both Office 1 and Office 2 (Latitude/Longitude) display first. (It seems like when you pass multiple LatLng combinations as the bounds it does not do this. Would like to confirm it is not possible.)
Shows only places that are food related. (I believe with Autocomplete this is not possible because it is restricted to passing in only certain place types)
Here is the closest I could get to what I am trying to achieve. However it only works correctly if I pass in a single LatLng for either Office 1 or Office 2, but not both.
<script type="text/javascript">
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-33.8902, 151.1759),
new google.maps.LatLng(-60.8474, 200.2631));
var input = document.getElementById('searchTextField');
var options = {
bounds: defaultBounds,
types: ['establishment']
};
autocomplete = new google.maps.places.Autocomplete(input, options);
</script>
The LatLngBounds takes a south-west co-ordinate as its first argument, and a north-east as a second. In your example, your second co-ordinate is more southern than the first and so the bounds are invalid:
This alternative ought to work regardless of relative position of the points:
var defaultBounds = new google.maps.LatLngBounds(new google.maps.LatLng(-33.8902, 151.1759));
defaultBounds.extend(new google.maps.LatLng(-60.8474, 200.2631));

OpenLayers LonLat transform

I want to use decimal Lon and Lat like Google Maps uses. But it seems I need to transform the LonLat object in OpenLayers, e.g.
var map, layer;
function init(){
map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.OSM( "Simple OSM Map");
map.addLayer(layer);
map.setCenter(
new OpenLayers.LonLat(-1.60400390625, 54.07228265560386).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 6
);
var markers = new OpenLayers.Layer.Markers( "Markers" );
map.addLayer(markers);
var size = new OpenLayers.Size(21,25);
var offset = new OpenLayers.Pixel(0,0);
var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png', size, offset);
markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(-1.60400390625, 54.07228265560386).transform(new OpenLayers.Projection("EPSG:4326"),map.getProjectionObject()),icon));
}
Each time I place a marker the position needs to be transformed to EPSG:4326. Is there a way to tell the map to always use this projection?
Whether you can set the projection on a map or not, depends on which service you are using for the base layer. As far as I know, OSM only provides its rendered tiles in EPSG:900913, so there is no way around transforming your coordinates before adding them to the map. You could search for a service that provides its tiles in multiple projections, but I haven't seen one that is free to use so far. An alternative would be to render your own tiles in the needed projection and provide them through your own tile server.
Let's suppose you have such a map, you can change the projection using OpenLayers.Map.setOptions() like this:
map.setOptions({
projection: "EPSG:4326"
});
But you may also need to set some projection related properties, like maxExtent etc. See this question.

Categories

Resources