Geolocation

Locate yourself

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);
        });
}
};

Create a buffer around a point

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);
}

Generate an Isochrone/Isodistance

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 and ol.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 using vector_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);
                }
                }
}
}

Search Around

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);
                        }
                        })
}
}

Tracking Animation

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 to ol.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);