Search code examples
openlayersopenstreetmap

Display Marker With Labels in OSM


I want to integrate Google Maps into OSM because of Google API charges. So I want to show MarkerWithLabels in an OSM map. How would I achieve it? Function LoadVehicledata() used to display an icon on particular location works fine. But function DisplayMarker() does not display a label on a particular Lat Long. I want combine the above functions to show a label with icon on that Lat Long. I tried so many ways. Any suggestions?

<link href="~/Content/themes/ol.css" rel="stylesheet" />
    <script src="http://www.openlayers.org/api/OpenLayers.js"></script>
    <script src="~/Scripts/ol.js"></script>
<body>
    <div id="map" style="width: 100vw; height: 100vh;"></div>
    <div id="overlay" style="background-color: yellow; width: 20px; height: 20px; border-radius: 10px;">
        <label id="lblVehicle"> Vehicle </label>
    </div>
    <script>

        var map;
        var mapLat = 33.540008;
        var mapLng = -111.869822;
        var mapDefaultZoom = 6;
        var _vehData = [{ "vehicleID": 69, "latitude": 33.540008, "longitude": -111.869822, "course": 3.0, "speed": 0.0, "gpsDateTime": "2019-05-10T02:08:20", "cityCode": "PHX", "details": "69 st:2 ", "minsSinceLastGPS": 0, "status": 8, "assignedStatus": 0, "stops": 0, "guests": 0, "airportID": "CHT", "fleet": "ECAR", "peggedStatus": 1 }];
        initialize_map();
        function initialize_map() {
            map = new ol.Map({
                target: "map",
                layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                })
                ],
                view: new ol.View({
                    center: ol.proj.fromLonLat([mapLng, mapLat]),
                    zoom: mapDefaultZoom
                })
            });
        }

        function LoadVehicledata(){
            for (var i = 0; i < _vehData.length-1; i++) {
                add_map_point(_vehData[i].latitude, _vehData[i].longitude);

            }
        }
        function add_map_point(lat, lng) {
            var vectorLayer = new ol.layer.Vector({
                source: new ol.source.Vector({
                    features: [new ol.Feature({
                        geometry: new ol.geom.Point(ol.proj.transform([parseFloat(lng), parseFloat(lat)], 'EPSG:4326', 'EPSG:3857')),
                    })]
                }),
                style: new ol.style.Style({
                    image: new ol.style.Icon({
                        anchor: [0.5, -10],
                        anchorXUnits: "fraction",
                        anchorYUnits: "fraction",
                        src: "/Images/ic_info.png"
                    })
                })
            });
            map.addLayer(vectorLayer);

        }

        function DisplayMarker() {
            var layer = new ol.layer.Tile({
                source: new ol.source.OSM()
            });


            var interaction = new ol.interaction.DragRotateAndZoom();


            var control = new ol.control.FullScreen();


            for (var i = 0; i < _vehData.length - 1; i++) {

                var overlay = new ol.Overlay({

                    position: ol.proj.fromLonLat([_vehData[i].latitude, _vehData[i].longitude], 'EPSG:4326', 'EPSG:3857'),
                    element: document.getElementById('overlay')
                });


                var view = new ol.View({

                    center: ol.proj.fromLonLat([_vehData[i].latitude, _vehData[i].longitude], 'EPSG:4326', 'EPSG:3857'),
                    zoom: 6
                });

                map.addOverlay(overlay);
                map.setView(view);

            }
        }
    </script>
</body>

Solution

  • Overlays are usually used to display information when you click or hover on a feature. To show labels with features at all times add a text style to the style and use a style function to set the label text for each feature, which should be set as a property of the feature. It will be more efficient to put your features in a single layer instead of creating one for each feature.

    function LoadVehicledata(){
        for (var i = 0; i < _vehData.length-1; i++) {
            add_map_point(_vehData[i].latitude, _vehData[i].longitude, _vehData[i].vehicleID);
        }
    }
    
    var style = new ol.style.Style({
        image: new ol.style.Icon({
            anchor: [0.5, -10],
            anchorXUnits: "fraction",
            anchorYUnits: "fraction",
            src: "/Images/ic_info.png"
        }),
        text: new ol.style.Text({
            font: '12px Calibri,sans-serif',
            fill: new ol.style.Fill({
                color: '#000'
            }),
            stroke: new ol.style.Stroke({
                color: '#fff',
                width: 3
            })
        })                       
    });
    
    var vectorLayer = new ol.layer.Vector({
        source: new ol.source.Vector(),
        style: function(feature) {
            style.getText().setText(feature.get('label'));
            return style;
        }
    });
    map.addLayer(vectorLayer);
    
    function add_map_point(lat, lng, label) {
        vectorLayer.getSource().addFeature(
            new ol.Feature({
                geometry: new ol.geom.Point(ol.proj.transform([parseFloat(lng), parseFloat(lat)], 'EPSG:4326', 'EPSG:3857')),
                label: label
            })
        )
    }
    

    The text style is based on https://openlayers.org/en/v4.6.5/examples/vector-layer.html you will probably need to refine it for your application.