Search code examples
openlayersopenstreetmapgeojsonopenlayers-3

How to render Array of coordinates for line map using OpenLayers?


I have a endpoint /geomap_data/ that I am using to return customer_sites in the console log in browser which shows the following which is Sites Coordinates, Customer coordinates:

0: "[53.50119612705815, -1.1270833894501477], [53.34474, -3.01101]"
1: "[53.50119612705815, -1.1270833894501477], [53.34474, -3.01101]"
2: "[52.04061648544843, -0.6655072691644374], [51.90829, -0.5127]"
3: "[52.04061648544843, -0.6655072691644374], [51.90829, -0.5127]"
4: "[52.04061648544843, -0.6655072691644374], [51.90829, -0.5127]"

I am able to render a map with 1 line using the code below with fake coordinates:

 $(document).ready(function(){
        var customer_sites = [];
        $.ajax({
            dataType: 'json',
            url: '/geomap_data/',
            success: function(json) {
                console.log('Moo')
                customer_sites = json;
            },
            async:false
        });
    
    console.log(customer_sites);
    
    var map = new ol.Map({
        target: 'GeoMap',
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        view: new ol.View({
          center: ol.proj.fromLonLat([3.8, 51.1]),
          zoom: 10
        })
      });
      var myView = map.getView();
      var myStyle = new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: 'blue',
          width: 5
        })
      });
      var myVectorSource = new ol.source.Vector();
      var point1 = ol.proj.transform([3.8, 51.20], 'EPSG:4326', 'EPSG:3857');
      var point2 = ol.proj.transform([4, 51], 'EPSG:4326', 'EPSG:3857');
      var points = [point1, point2];
      var myLine = new ol.geom.LineString(points);
      
      var myproj = myView.getProjection();
      var length = ol.sphere.getLength(myLine);
      
      var segment = new ol.Feature({
        geometry: myLine,
        style: myStyle
      });
      
      myVectorSource.addFeature(segment);
      // Create vector layer attached to the vector source.
      var vectorLayer = new ol.layer.Vector({
        source: myVectorSource,
        style: myStyle
      });
      
      // Add the vector layer to the map.
      map.addLayer(vectorLayer);
    
});

I know I can convert the customer_sites json into Geojson using the below code:

geojsonObject = {
    'type': 'FeatureCollection',
    'crs': {
        'type': 'name',
        'properties': {
            'name': 'EPSG:3857',
        },
    },
    'features': [
        {
            'type': 'Feature',
            'geometry': {
                'type': 'MultiLineString',
                'coordinates': customer_sites
            },
        }
    ]
};

And then I should be able to read the GeoJson and add it to the vector layer using the following:

var vectorLayer = new ol.layer.Vector({
    source: new ol.source.Vector({
        features: new ol.format.GeoJSON().readFeatures(geojsonObject)
    }),

But the the customer_sites does not work..

I think because the coordinates "[53.50119612705815, -1.1270833894501477], [53.34474, -3.01101]" are the wrong way around and they are not in a nested array? Althoguh i'm not 100% sure

Thanks!


Solution

  • You could parse the data directly into a MultiLineString geometry. Use .reverse() to swap the coordinate order.

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.14.1/css/ol.css" type="text/css">
        <style>
          html, body, .map {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
          }
        </style>
        <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.14.1/build/ol.js"></script>
      </head>
      <body>
        <div id="map" class="map"></div>
        <script type="text/javascript">
    
          var data = [
            "[53.50119612705815, -1.1270833894501477], [53.34474, -3.01101]",
            "[53.50119612705815, -1.1270833894501477], [53.34474, -3.01101]",
            "[52.04061648544843, -0.6655072691644374], [51.90829, -0.5127]",
            "[52.04061648544843, -0.6655072691644374], [51.90829, -0.5127]",
            "[52.04061648544843, -0.6655072691644374], [51.90829, -0.5127]"
          ];
          var features = new ol.Feature(
            new ol.geom.MultiLineString(
              data.map(function(row) { 
                return JSON.parse('[' + row + ']').map(function(coordinate) {
                  return coordinate.reverse();
                });
              })
            ).transform('EPSG:4326', 'EPSG:3857')
          );
          var map = new ol.Map({
            target: 'map',
            layers: [
              new ol.layer.Tile({
                source: new ol.source.OSM()
              }),
              new ol.layer.Vector({
                source: new ol.source.Vector({
                  features: [features]
                }),
                style: new ol.style.Style({
                  stroke: new ol.style.Stroke({
                    color: 'blue',
                    width: 5
                  })
                })
              })
            ],
            view: new ol.View()
          });
          map.getView().fit(features.getGeometry());
        </script>
      </body>
    </html>