To know to your current position in the map, follow the below steps:
-
Create a new instance of
ol.Geolocation
class and set the trackingOptions enableHighAccuracy to true
var geolocation = new ol.Geolocation({ trackingOptions: { enableHighAccuracy: true }, projection: map.getView().getProjection() });
- To enable your browser to detect your location set tracking to true
geolocation.setTracking(true);
-
To get an approximate buffer area around your location create a new instance of
ol.Feature
class and set the geometry of the feature to geolocation accuracy geometry
var accuracyFeature = new ol.Feature(); geolocation.on('change:accuracyGeometry', function() { accuracyFeature.setGeometry(geolocation.getAccuracyGeometry()); });
-
Listen to the change position event on geolocation object and get the coordinates and push features to the new instance of
GCUI.Layer.StandardVector
class
geolocation.on('change:position', function() { var coordinates = geolocation.getPosition(); positionFeature.setGeometry(coordinates ? new ol.geom.Point(coordinates) : null); var vector_layer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [accuracyFeature,positionFeature] }) });
HTML
<div style="position: absolute; z-index: 5000; left: 65px;"> <button type="button" onclick="GCUI.locate.geoLocate()">Geolocate</button> </div> <div id="maploc" style="height:300px"></div>
JavaScript
var options = { server : 'https://api.geoconcept.com/EU/GCW/geoconcept-web/wmts', layer : 'STANDARD', x : 260803, y : 6250829, scale : 1 }; var map = new GCUI.Map('maploc', options); GCUI.locate = { geoLocate : function() { var geolocation = new ol.Geolocation({ // enableHighAccuracy must be set to true to have the heading value. trackingOptions: { enableHighAccuracy: true }, projection: map.getView().getProjection() }); geolocation.setTracking(true); var positionFeature = new ol.Feature(); positionFeature.setStyle(new ol.style.Style({ image: new ol.style.Circle({ radius: 6, fill: new ol.style.Fill({ color: '#3399CC'}), stroke: new ol.style.Stroke({ color: '#fff', width: 2 }) }) })); var accuracyFeature = new ol.Feature(); geolocation.on('change:accuracyGeometry', function() { accuracyFeature.setGeometry(geolocation.getAccuracyGeometry()); }); geolocation.on('change:position', function() { var coordinates = geolocation.getPosition(); positionFeature.setGeometry(coordinates ? new ol.geom.Point(coordinates) : null); var vector_layer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [accuracyFeature,positionFeature] }) }); map.addLayer(vector_layer); map.zoomToExtent(positionFeature.getGeometry().getExtent()); map.getView().setZoom(10); }); } };
To generate a buffer around a point, follow the below steps:
-
Create a new instance of the
ol.Feature
class and set the geometry of the feature to a circle geometry and push the buffer area which needs to be created around that point
var circleBuffer = new GCUI.ol.Feature({ geometry: new GCUI.ol.geom.Circle([258353.06,6240408.91], 4000) });
- Set the style of the buffer according to your interest
var buffer_style = [new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255,255,255,0.03)' }), stroke: new ol.style.Stroke({ width: 2 })}) ];
-
Set the style of the
ol.Feature
object to the style created and add the feature to the vector source.
circleBuffer.setStyle(buffer_style); vectorSource.addFeature(circleBuffer);
HTML
<div id="map1" style="height:300px"></div>
JavaScript
var options = { server : 'https://api.geoconcept.com/EU/GCW/geoconcept-web/wmts', layer : 'STANDARD' }; var map = new GCUI.Map('map1', options); map.onEvent("load", onMapLoaded); function onMapLoaded() { var vectorSource = new ol.source.Vector({}); var point_feature_1 = new ol.Feature({ geometry: new ol.geom.Point([258353.06,6240408.91]), Name: "Groupe Geoconcept", Address: "152 Avenue Aristide Briand, 92220 Bagneux, France" }); vectorSource.addFeature(point_feature_1); vector_layer = new GCUI.Layer.StandardVector({ source: vectorSource }); map.addLayer(vector_layer); //Set the source of the point style to a custom image var point_style = new ol.style.Style({ image: new ol.style.Icon({ crossOrigin: 'anonymous', src: 'https://i.ibb.co/SBRmrF5/show-Image.png' }) }); var buffer_style = [new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255,255,255,0.03)' }), stroke: new ol.style.Stroke({ color: 'rgba(30,144,255,1)', width: 2 })}) ]; var circleBuffer = new GCUI.ol.Feature({ geometry: new GCUI.ol.geom.Circle([258353.06,6240408.91], 4000) }); circleBuffer.setStyle(buffer_style); vectorSource.addFeature(circleBuffer); vector_layer.setStyle(point_style); extent = vectorSource.getExtent(); map.getView().fit(extent); map.getView().setZoom(12); }
To generate an Isochrone/Isodistance from a location, follow the below steps:
- Create a isochrone/isodistance webservice request and pass the start coordinates, distance/time for which the isonchrone/isodistance needs to be generated and method to get back a isochrone/isodistance JSON file
const url = 'https://api.geoconcept.com/EU/GCW/geoconcept-web/api/lbs/isochrone/v4.json?location=' + location + '&distance=' + distance + '&time=' + time + '&method=' + method + '&appkey=' + apikey + '&apptoken=' + apptoken';
- Read the Isochrone/Isodistance WKT geometry from the response received. Reproject it to the map projection if required.
isochrone_feature = ol.format.WKT.prototype.readFeature(parsedjson.wktGeometry,{ dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' });
- Create a vector layer and push the isochrone/isodistance feature created.
vector_layer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [isochrone_feature] }) });
- Add the vector layer to the existing map
map.addLayer(vector_layer);
-
Define the style of the point using
ol.style.Fill
andol.style.Stroke
classes
var fill = new ol.style.Fill({ color: [158, 100, 213, 0.5] }); var stroke = new ol.style.Stroke({ color: [158, 100, 213, 0.5], width: 2 });
-
Create a new instance of the
ol.style.Style
class and set the style of the layer usingvector_layer.setStyle()
var style = new ol.style.Style({ image: new ol.style.Circle({ fill: fill, stroke: stroke, radius: 5 }), fill: fill, stroke: stroke }); vector_layer.setStyle(style);
HTML
<div style="position: absolute; z-index: 5000; left: 65px;"> <input type="text" id="location" placeholder="Location" value="2.321134,48.796575"> <input type="text" id="distance" placeholder="Distance" value="10000"> <input type="text" id ="time" placeholder="Time" value="1800"> <input type="text" id ="method" placeholder="Method" value="time"> <button type="button" onclick="GCUI.isoexamples.getIsochrone()">Generate Isochrone</button> </div> <div id="mapDiv1" style="height:300px"></div>
JavaScript
var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 0c-4.198 0-8 3.403-8 7.602 0 4.198 3.469 9.21 8 16.398 4.531-7.188 8-12.2 8-16.398 0-4.199-3.801-7.602-8-7.602zm0 11c-1.657 0-3-1.343-3-3s1.343-3 3-3 3 1.343 3 3-1.343 3-3 3z"/></svg>'; var options = { server : 'https://api.geoconcept.com/EU/GCW/geoconcept-web/wmts', layer : 'STANDARD', x : 260803, y : 6250829, scale : 8 }; var map = new GCUI.Map('mapDiv1', options); GCUI.isoexamples = { getIsochrone : function () { var location = document.getElementById("location").value; var distance = document.getElementById("distance").value; var time = document.getElementById("time").value; var method = document.getElementById("method").value; const request = new XMLHttpRequest(); const url = 'https://api.geoconcept.com/EU/GCW/geoconcept-web/api/lbs/isochrone/v4.json?location=' + location + '&distance=' + distance + '&time=' + time + '&method=' + method + '&appkey=' + $("input[name=apikey]").val() + '&apptoken=' + $("input[name=apitoken]").val(); request.open("GET", url); request.send(); // Treatment of the output JSON to display the information on the popup request.onreadystatechange=(e)=>{ if(request.readyState == 4 && request.status == 200) { var responseJson = request.responseText; parsedjson = JSON.parse(responseJson); if (map.getLayers().array_.length > 1){ location_pointlayer.getSource().removeFeature(location_feature); vector_layer.getSource().removeFeature(isochrone_feature); } // Adding a vector layer to the map var location_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(location.split(',').shift()),parseFloat(location.split(',').pop())])); location_feature = new ol.Feature({}); location_feature.setGeometry(location_geom); location_pointlayer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [location_feature] }) }); map.addLayer(location_pointlayer); isochrone_feature = ol.format.WKT.prototype.readFeature(parsedjson.wktGeometry,{ dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' }); vector_layer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [isochrone_feature] }) }); map.addLayer(vector_layer); //Adding a style to the vector layer var location_style = new ol.style.Style({ image: new ol.style.Icon({ crossOrigin: 'anonymous', src: 'https://i.ibb.co/cCJjRvj/Finish.png' }) }); var fill = new ol.style.Fill({ color: [158, 100, 213, 0.5] }); var stroke = new ol.style.Stroke({ color: [158, 100, 213, 0.5], width: 5 }); var style = new ol.style.Style({ image: new ol.style.Circle({ fill: fill, stroke: stroke, radius: 5 }), fill: fill, stroke: stroke }); location_pointlayer.setStyle(location_style); vector_layer.setStyle(style); extent = isochrone_feature.getGeometry().getExtent(); map.getView().fit(extent); } } } }
To search around and find the closest resource , follow the below steps:
- Define the start location
var location_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(location.split(',').shift()),parseFloat(location.split(',').pop())])); location_feature = new ol.Feature({Name: "Start Location",id:"0",distanceMeters:0}); location_feature.setGeometry(location_geom); location_pointlayer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [location_feature] }) });
- Define the list of finish locations whose distance needs to be calculated
var resource1_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(resource1.split(',').shift()),parseFloat(resource1.split(',').pop())])); resource1_feature = new ol.Feature({Name: "Resource1",id:"1",distanceMeters:0}); resource1_feature.setGeometry(resource1_geom); var resource2_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(resource2.split(',').shift()),parseFloat(resource2.split(',').pop())])); resource2_feature = new ol.Feature({Name: "Resource2",id:"2",distanceMeters:0}); resource2_feature.setGeometry(resource2_geom); var resource3_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(resource3.split(',').shift()),parseFloat(resource3.split(',').pop())])); resource3_feature = new ol.Feature({Name: "Resource3",id:"3",distanceMeters:0}); resource3_feature.setGeometry(resource3_geom); var resource4_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(resource4.split(',').shift()),parseFloat(resource4.split(',').pop())])); resource4_feature = new ol.Feature({Name: "Resource4",id:"4",distanceMeters:0}); resource4_feature.setGeometry(resource4_geom); var resource5_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(resource5.split(',').shift()),parseFloat(resource5.split(',').pop())])); resource5_feature = new ol.Feature({Name: "Resource5",id:"5",distanceMeters:0}); resource5_feature.setGeometry(resource5_geom); resource_pointlayer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [resource1_feature,resource2_feature,resource3_feature,resource4_feature,resource5_feature] }) });
- Construct the BODY of the request with the start location and the list of resources and POST it to searchAround webservices to get the response.
const url = 'https://api.geoconcept.com/EU/GCW/geoconcept-web/api/lbs/searchAround/v4.json?' + '&appkey=' + appkey + '&apptoken=' + apptoken; data = '{"location": {"x":' + parseFloat(location.split(',').shift()) + ',"y":' + parseFloat(location.split(',').pop()) + '},"resources": [{"id":' + 1 + ',"x":' + parseFloat(resource1.split(',').shift()) + ',"y":' + parseFloat(resource1.split(',').pop()) + '},{"id": ' + 2 + ',"x":' + parseFloat(resource2.split(',').shift()) + ',"y":' + parseFloat(resource2.split(',').pop()) + '},{"id": ' + 3 + ',"x":' + parseFloat(resource3.split(',').shift()) + ',"y":' + parseFloat(resource3.split(',').pop()) + '},{"id": ' + 4 + ',"x":' + parseFloat(resource4.split(',').shift()) + ',"y":' + parseFloat(resource4.split(',').pop()) + '},{"id": ' + 5 + ',"x":' + parseFloat(resource5.split(',').shift()) + ',"y":' + parseFloat(resource5.split(',').pop()) + '}],"method":"time","reverse": "false"}';
- Treat the response and display the results on to the existing map.
vector_layer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: search_around_points }), style: searchStyle }); map.addLayer(vector_layer);
HTML
<style> .anchorright#ol-popup { right: -30px; } .anchorright#ol-popup:after { right: 20px; } .anchorright#ol-popup:before { right: 20px; } .anchorbottom#ol-popup { bottom: 11px; } .anchorbottom#ol-popup:after, .anchorbottom#ol-popup:before { top: 100%; } #ol-popup-content.content { max-height: 25em; overflow-y: auto; } .#ol-popup{ padding-top: 2em; padding-right: 0.35em; } .anchorbottom#ol-popup:after { border-top-color: white; } .anchorbottom#ol-popup:before { border-top-color: #cccccc; } .anchorleft#ol-popup { left: -25px; } .anchorleft#ol-popup:after { left: 25px; } .anchorleft#ol-popup:before { left: 25px; } .anchortop#ol-popup { top: 11px; } .anchortop#ol-popup:after, .anchortop#ol-popup:before { bottom: 100%; } .anchortop#ol-popup:after { border-bottom-color: white; } .anchortop#ol-popup:before { border-bottom-color: #cccccc; } #ol-popup { position: absolute; background-color: white; -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); padding: 15px; border-radius: 5px; border: 1px solid #cccccc; min-width: 280px; } #ol-popup:after, #ol-popup:before { border: solid transparent; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } #ol-popup:after { border-width: 10px; margin-left: -10px; } #ol-popup:before { border-width: 11px; margin-left: -11px; } #ol-popup-closer { text-decoration: none; position: absolute; top: 2px; right: 8px; font-family: Icons; } #ol-popup-closer:hover { cursor: pointer; color: #004687; } #ol-popup-closer:after { content: "✖"; } #ol-popup .pages { text-align: right; position: relative; right: -1em; bottom: -0.8em; } #ol-popup .pages i { cursor: pointer; } #ol-popup .pages > * { display: inline-block; } #ol-popup .pages i.disabled { cursor: default; } .gcuiAnchoredContentData { height: 100%; width: 100%; overflow-y: auto; overflow-x: hidden; } .gcuiAnchoredContentData .table-width { width: 50%; } .gcuiAnchoredContentData .ui.table .right.aligned .content { text-align: right; margin-right: .2em; color: #808080; } .gcuiAnchoredContentData .ui.table .content { color: #000000; border: none !important; } .gcuiAnchoredContentData .ui.table td { padding: .25em; border: none !important; } .gcuiAnchoredContentData .ui.table, th, td { border: none !important; } .ol-custom-overviewmap, .ol-custom-overviewmap.ol-uncollapsible { bottom: auto; left: auto; right: 0; top: 0; } .ol-custom-overviewmap:not(.ol-collapsed) { border: 1px solid black; } .ol-custom-overviewmap .ol-overviewmap-map { border: none; width: 300px; } .ol-custom-overviewmap .ol-overviewmap-box { border: 2px solid red; } .ol-custom-overviewmap:not(.ol-collapsed) button{ bottom: auto; left: auto; right: 1px; top: 1px; } .ol-rotate { top: 170px; right: 0; } </style> <div style="position: absolute; z-index: 5000; left: 15px;"> <input type="text" id="slocation" placeholder="Start Location" value="-1.553927,47.21858" size="15"> <input type="text" id="Resource1" placeholder="Resource1" value="-1.576829,47.224742" size="15"> <input type="text" id ="Resource2" placeholder="Resource2" value="-1.544900,47.220649" size="15"> <input type="text" id ="Resource3" placeholder="Resource3" value="-1.534977,47.210036" size="15"> <input type="text" id ="Resource4" placeholder="Resource4" value="-1.550059,47.224586" size="15"> <input type="text" id ="Resource5" placeholder="Resource5" value="-1.577197,47.202243" size="15"><br> <button type="button" onclick="GCUI.examples.searchAround()" >Search Around</button> </div> <div id="mapDiv2" style="height:300px"></div>
JavaScript
var map; var resource_fill; var resource_stroke; var resource_text; var data; var final_data; var input_data = null; var search_around_points = []; var vector_layer; var options = { server : 'https://api.geoconcept.com/EU/GCW/geoconcept-web/wmts', layer : 'STANDARD', x : 260803, y : 6250829, scale : 8 }; var map = new GCUI.Map('mapDiv2', options); map.onEvent("load", onMapLoaded); function onMapLoaded() { var location = document.getElementById("slocation").value; var resource1 = document.getElementById("Resource1").value; var resource2 = document.getElementById("Resource2").value; var resource3 = document.getElementById("Resource3").value; var resource4 = document.getElementById("Resource4").value; var resource5 = document.getElementById("Resource5").value; var location_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(location.split(',').shift()),parseFloat(location.split(',').pop())])); location_feature = new ol.Feature({Name: "Start Location",id:"0",distanceMeters:0}); location_feature.setGeometry(location_geom); location_pointlayer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [location_feature] }) }); var resource1_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(resource1.split(',').shift()),parseFloat(resource1.split(',').pop())])); resource1_feature = new ol.Feature({Name: "Resource1",id:"1",distanceMeters:0}); resource1_feature.setGeometry(resource1_geom); var resource2_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(resource2.split(',').shift()),parseFloat(resource2.split(',').pop())])); resource2_feature = new ol.Feature({Name: "Resource2",id:"2",distanceMeters:0}); resource2_feature.setGeometry(resource2_geom); var resource3_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(resource3.split(',').shift()),parseFloat(resource3.split(',').pop())])); resource3_feature = new ol.Feature({Name: "Resource3",id:"3",distanceMeters:0}); resource3_feature.setGeometry(resource3_geom); var resource4_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(resource4.split(',').shift()),parseFloat(resource4.split(',').pop())])); resource4_feature = new ol.Feature({Name: "Resource4",id:"4",distanceMeters:0}); resource4_feature.setGeometry(resource4_geom); var resource5_geom = new ol.geom.Point(ol.proj.fromLonLat([parseFloat(resource5.split(',').shift()),parseFloat(resource5.split(',').pop())])); resource5_feature = new ol.Feature({Name: "Resource5",id:"5",distanceMeters:0}); resource5_feature.setGeometry(resource5_geom); resource_pointlayer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [resource1_feature,resource2_feature,resource3_feature,resource4_feature,resource5_feature] }) }); var location_fill = new ol.style.Fill({ color: [71, 176, 67, 0.9] }); resource_fill = new ol.style.Fill({ color: 'red' }); var location_stroke = new ol.style.Stroke({ color: [255, 255, 255, 1], width: 2 }); resource_stroke = new ol.style.Stroke({ color: [255, 255, 255, 1], width: 2 }); var location_text = new ol.style.Text({ font: '10px Open Sans', text: 'S', fill: new ol.style.Fill({ color: [255, 255, 255, 1] }) }); resource_text = new ol.style.Text({ font: '10px Open Sans', text: 'F', fill: new ol.style.Fill({ color: [255, 255, 255, 1] }) }); var location_style = new ol.style.Style({ image: new ol.style.Circle({ fill: location_fill, stroke: location_stroke, text:location_text, radius: 10 }), fill: location_fill, stroke: location_stroke, text:location_text }); var resource_style = new ol.style.Style({ image: new ol.style.Circle({ fill: resource_fill, stroke: resource_stroke, text:resource_text, radius: 10 }), fill: resource_fill, stroke: resource_stroke, text:resource_text }); location_pointlayer.setStyle(location_style); resource_pointlayer.setStyle(resource_style); map.addLayer(location_pointlayer); map.addLayer(resource_pointlayer); map.zoomToExtent(resource_pointlayer.getSource().getExtent()); //select interaction working on "click" var selectClick = new ol.interaction.Select({ condition: ol.events.condition.click }); if (selectClick !== null) { map.addInteraction(selectClick); selectClick.on('select', function(e) { var feature = e.target.getFeatures().getArray(); if (feature.length >= 1) { var opt_options = "<div class='gcuiAnchoredContentData'><table class='ui very basic table unstackable' cellspacing='0' cellpadding='0'><tbody><tr><td class='right aligned'><div class='content'>Name</div></td><td><div class='content'>" + feature[0].values_.Name + "</div></td></tr><tr><td class='right aligned'><div class='content'>Identifier</div></td><td><div class='content'>" + feature[0].values_.id + "</div></td></tr>" + "</div></td></tr><tr><td class='right aligned'><div class='content'>DistanceInMeters</div></td><td><div class='content'>" + feature[0].values_.distanceMeters + "</div></td></tr></tbody></table></div>"; var popup = new GCUI.Control.Popup(map, feature[0].values_.geometry.flatCoordinates, {content : opt_options}); map.addOverlay(popup); popup.initialize(feature[0].values_.geometry.flatCoordinates); } }); } } GCUI.examples = { searchAround : function () { if (search_around_points.length > 1){ search_around_points = []; vector_layer.getSource().clear(); } var location = document.getElementById("slocation").value; var resource1 = document.getElementById("Resource1").value; var resource2 = document.getElementById("Resource2").value; var resource3 = document.getElementById("Resource3").value; var resource4 = document.getElementById("Resource4").value; var resource5 = document.getElementById("Resource5").value; const search_url = 'https://api.geoconcept.com/EU/GCW/geoconcept-web/api/lbs/searchAround/v4.json?' + '&appkey=' + $("input[name=apikey]").val() + '&apptoken=' + $("input[name=apitoken]").val(); post_body = '{"location": {"x":' + parseFloat(location.split(',').shift()) + ',"y":' + parseFloat(location.split(',').pop()) + '},"resources": [{"id":' + 1 + ',"x":' + parseFloat(resource1.split(',').shift()) + ',"y":' + parseFloat(resource1.split(',').pop()) + '},{"id": ' + 2 + ',"x":' + parseFloat(resource2.split(',').shift()) + ',"y":' + parseFloat(resource2.split(',').pop()) + '},{"id": ' + 3 + ',"x":' + parseFloat(resource3.split(',').shift()) + ',"y":' + parseFloat(resource3.split(',').pop()) + '},{"id": ' + 4 + ',"x":' + parseFloat(resource4.split(',').shift()) + ',"y":' + parseFloat(resource4.split(',').pop()) + '},{"id": ' + 5 + ',"x":' + parseFloat(resource5.split(',').shift()) + ',"y":' + parseFloat(resource5.split(',').pop()) + '}],"method":"time","reverse": "false"}'; $.ajax({ url : search_url, type: 'POST', data: post_body, dataType: "json", contentType:"application/json;charset\x3dutf-8", success: function(result){ parsedjson = result; resource_pointlayer.getSource().clear(); for(i = 0; i<parsedjson.searchAroundResult.length; i++){ parsedjson.searchAroundResult[i].id = parseInt(parsedjson.searchAroundResult[i].id) } final_data = $.extend(true,JSON.parse(post_body).resources,parsedjson.searchAroundResult.sort(function(a, b){return a.id - b.id})); final_data.sort(function(a, b){return a.distanceMeters - b.distanceMeters}) for (i=0;i<final_data.length;i++){ var xy = ol.proj.fromLonLat([final_data[i].x,final_data[i].y]); search_around_points.push(new ol.Feature({ geometry: new ol.geom.Point(xy), Name: 'Resource' + (i+1), id: parseInt(final_data[i].id), distanceMeters: final_data[i].distanceMeters, Rank: (i+1) })); } function searchStyle(feature) { var resource_icon = new ol.style.Text({ font: '10px Open Sans', text: feature.get('Rank').toString(), fill: new ol.style.Fill({ color: 'white' }) }); var style = new ol.style.Style({ image: new ol.style.Circle({ radius: 10, text: resource_icon, stroke: new ol.style.Stroke({ color: 'white', width: 2 }), fill: new ol.style.Fill({ color: 'red' }) }), text: resource_icon }); return [style]; } vector_layer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: search_around_points }), style: searchStyle }); map.addLayer(vector_layer); }, error: function(error){ alert(error); } }) } }
To animate a GPS tracking , follow the below steps:
-
Define the route in WKT geometry which needs to be tracked and read the WKT feature using the function
ol.format.WKT.prototype.readFeature
- Reproject it to the map projection if necessary
var polyline = "LINESTRING (2.364632 48.864657,2.364579 48.861966,2.364587 48.861336,2.364537 48.859457,2.364438 48.857838,2.364233 48.856426,2.362948 48.854603,2.366468 48.853520,2.368516 48.853212,2.367298 48.850843,2.365799 48.847646,2.367620 48.845831,2.364568 48.844123,2.361985 48.840291,2.358277 48.835208,2.356520 48.832845,2.359491 48.832237,2.365139 48.829188,2.366523 48.826991,2.369328 48.821730,2.376556 48.816573,2.383493 48.810967,2.396966 48.817444,2.406021 48.824962,2.419579 48.818368,2.435368 48.808749)"; var line_feature = ol.format.WKT.prototype.readFeature(polyline,{ dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' }); var routeFeature = new ol.Feature({ type: 'route', geometry: line_feature.getGeometry() });
-
Define the start point, start marker and end point by creating a new instance of the class
ol.geom.Point
-
Push the created
ol.geom.Point
tool.Feature
var firstPoint = new ol.geom.Point([263229,6251927]); geoMarker = new ol.Feature({ type:'geoMarker'}); geoMarker.setGeometry(firstPoint); startMarker = new ol.Feature({ type:'startMarker'}); startMarker.setGeometry(firstPoint); var lastPoint = new ol.geom.Point([271103,6242472]); endMarker = new ol.Feature({ type:'endMarker'}); endMarker.setGeometry(lastPoint);
- Push all the features to the vector layer and add the layer to the exiting Geoconcept map.
vectorlayer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [geoMarker,routeFeature,startMarker,endMarker] }), style: function(feature) { // hide geoMarker if animation is active if (animating && feature.get('type') === 'geoMarker') { return null; } return styles[feature.get('type')]; } }); map.addLayer(vectorlayer);
- Get all the coordinates of the route and the total route length using the below statements.
var routeCoords = line_feature.getGeometry().flatCoordinates; var routeLength = line_feature.getGeometry().flatCoordinates.length;
- While animating calculate the elapsed time and create an index.
- Use the index value to move the current point from one vertices to other to show the movement of the location on the map.
if (animating) { var elapsedTime = frameState.time - now; var index = Math.round(10 * elapsedTime / 1000); if (index >= routeLength) { stopAnimation(true); return; } var currentPoint = new ol.geom.Point([routeCoords[index],routeCoords[index+1]]); var feature = new ol.Feature(currentPoint); vectorContext.drawFeature(feature, styles.geoMarker); }
HTML
<div style="position: absolute; z-index: 5000; left: 65px;"> <button type="button" id="start-animation">Start Animation</button> </div> <div id="mapDiv3" style="height:300px"></div>
JavaScript
var center =[260803, 6250829]; var options = { server : 'https://api.geoconcept.com/EU/GCW/geoconcept-web/wmts', layer : 'STANDARD', x : 260803, y : 6250829, scale : 1 }; var map = new GCUI.Map('mapDiv3', options); var polyline = "LINESTRING (2.364632 48.864657,2.364579 48.861966,2.364587 48.861336,2.364537 48.859457,2.364438 48.857838,2.364233 48.856426,2.362948 48.854603,2.366468 48.853520,2.368516 48.853212,2.367298 48.850843,2.365799 48.847646,2.367620 48.845831,2.364568 48.844123,2.361985 48.840291,2.358277 48.835208,2.356520 48.832845,2.359491 48.832237,2.365139 48.829188,2.366523 48.826991,2.369328 48.821730,2.376556 48.816573,2.383493 48.810967,2.396966 48.817444,2.406021 48.824962,2.419579 48.818368,2.435368 48.808749)"; var line_feature = ol.format.WKT.prototype.readFeature(polyline,{ dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' }); var routeFeature = new ol.Feature({ type: 'route', geometry: line_feature.getGeometry() }); var routeCoords = line_feature.getGeometry().flatCoordinates; var routeLength = line_feature.getGeometry().flatCoordinates.length; var firstPoint = new ol.geom.Point([263229,6251927]); geoMarker = new ol.Feature({ type:'geoMarker'}); geoMarker.setGeometry(firstPoint); startMarker = new ol.Feature({ type:'startMarker'}); startMarker.setGeometry(firstPoint); var lastPoint = new ol.geom.Point([271103,6242472]); endMarker = new ol.Feature({ type:'endMarker'}); endMarker.setGeometry(lastPoint); var styles = { 'route': new ol.style.Style({ stroke: new ol.style.Stroke({ color: [0, 70, 135, 1], width: 6 }) }), 'startMarker': new ol.style.Style({ image: new ol.style.Icon({ crossOrigin: 'anonymous', src: 'https://i.ibb.co/cCJjRvj/Finish.png' }) }), 'geoMarker': new ol.style.Style({ image: new ol.style.Circle({ fill: new ol.style.Fill({ color: 'white' }), stroke: new ol.style.Stroke({ color: [0, 70, 135, 1], width: 6 }), radius: 7 }) }), 'endMarker': new ol.style.Style({ image: new ol.style.Icon({ crossOrigin: 'anonymous', src: 'https://i.ibb.co/VjGzprJ/Start.png' }) }) }; vectorlayer = new GCUI.Layer.StandardVector({ source: new ol.source.Vector({ features: [geoMarker,routeFeature,startMarker,endMarker] }), style: function(feature) { // hide geoMarker if animation is active if (animating && feature.get('type') === 'geoMarker') { return null; } return styles[feature.get('type')]; } }); map.addLayer(vectorlayer); map.zoomToExtent(vectorlayer.getSource().getExtent()); var animating = false; var now; var startButton = document.getElementById('start-animation'); var moveFeature = function(event) { var vectorContext = event.vectorContext; var frameState = event.frameState; if (animating) { var elapsedTime = frameState.time - now; var index = Math.round(10 * elapsedTime / 1000); if (index >= routeLength) { stopAnimation(true); return; } var currentPoint = new ol.geom.Point([routeCoords[index],routeCoords[index+1]]); var feature = new ol.Feature(currentPoint); vectorContext.drawFeature(feature, styles.geoMarker); } map.render(); }; function startAnimation() { if (animating) { stopAnimation(false); } else { animating = true; now = new Date().getTime(); startButton.textContent = 'Cancel Animation'; geoMarker.setStyle(null); map.getView().setCenter(center); map.on('postcompose', moveFeature); map.render(); } } function stopAnimation(ended) { animating = false; startButton.textContent = 'Start Animation'; var coord = ended ? routeCoords.slice(0,2) : routeCoords.slice(0,2); /** @type {module:ol/geom/Point~Point} */ (geoMarker.getGeometry()) .setCoordinates(coord); //remove listener map.on('postcompose', moveFeature); map.render(); } startButton.addEventListener('click', startAnimation, false);