wrdaigle
wrdaigle

Reputation: 43

Cannot load topojson object as openlayers layer

I'm using Open Layers and having trouble loading a map layer directly from a topojson object(as opposed to a URL).

The map should have a blue vector layer representing Mexico, but for some reason the layer doesn't get added to the map. It is not throwing any errors. I don't think it is a projection issue.

I have a situation where I have already loaded the topojson object outside of Open Layers, so I would like to use it directly as opposed to reloading from the URL.

  //Create a background layer
    var raster = new ol.layer.Tile({
      source: new ol.source.TileJSON({
        url: 'https://api.tiles.mapbox.com/v3/mapbox.world-dark.json?secure'
      })
    });


    //create a vector layer for the US using a a topojson URL as the input
    var style_world_RedBorder = new ol.style.Style({
      fill: new ol.style.Fill({
        color: 'rgba(0,0,0,0)'
      }),
      stroke: new ol.style.Stroke({
        color: 'rgba(255,0,0,1)',
        width: 1
      })
    });
    var vector_world = new ol.layer.Vector({
      source: new ol.source.Vector({
        url: 'https://openlayers.org/en/v4.6.5/examples/data/topojson/world-110m.json',
        format: new ol.format.TopoJSON({
          layers: ['countries']
        }),
        overlaps: false
      }),
      style: style_world_RedBorder
    });


    //create a vector layer for mexico using a topojson object as the input
    var style_mexico = new ol.style.Style({
      fill: new ol.style.Fill({
        color: 'rgba(0,255,0,0.25)'
      }),
      stroke: new ol.style.Stroke({
        color: 'rgba(0,255,0,1)',
        width: 1
      })
    });
    var mexicoData = {
      "type": "Topology",
      "arcs": [
        [
          [315, 1244],
          [121, -48],
          [171, 0],
          [110, 31],
          [90, -87],
          [21, -67],
          [84, -52],
          [29, 57],
          [76, 2],
          [115, -164],
          [24, -84],
          [118, -38],
          [-33, -124],
          [-5, -160],
          [41, -115],
          [77, -136],
          [82, -44],
          [182, 52],
          [42, 39],
          [23, 122],
          [142, 44],
          [70, -13],
          [-54, -137],
          [-2, -87],
          [-83, -45],
          [-111, 0],
          [32, -129],
          [-77, 0],
          [-29, -61],
          [-59, 16],
          [-101, 71],
          [-97, -59],
          [-194, 80],
          [-228, 121],
          [-93, 77],
          [-39, 78],
          [29, 76],
          [-38, 91],
          [-159, 194],
          [-48, 93],
          [-65, 50],
          [-110, 133],
          [-108, 200],
          [-53, -6],
          [11, -103],
          [108, -131],
          [132, -270],
          [-91, 6],
          [-11, 99],
          [-127, 75],
          [25, 97],
          [-99, 92],
          [-86, 206],
          [140, -2],
          [105, -40]
        ]
      ],
      "transform": {
        "scale": [0.016598932212296365, 0.013431657853810241],
        "translate": [-118.28916899999996, 15.262220000000072]
      },
      "objects": {
        "mexico": {
          "type": "GeometryCollection",
          "geometries": [{
            "arcs": [
              [0]
            ],
            "type": "Polygon",
            "properties": {
              "FIPS": "MX",
              "ISO2": "MX",
              "ISO3": "MEX",
              "UN": 484,
              "NAME": "Mexico",
              "AREA": 190869,
              "POP2005": 104266392,
              "REGION": 19,
              "SUBREGION": 13,
              "LON": -102.535,
              "LAT": 23.951
            }
          }]
        }
      }
    }
    var features = (new ol.format.TopoJSON({
      layers: ['mexico']
    })).readFeatures(mexicoData);
    var source = new ol.source.Vector({
      features: features,
      overlaps: false
    });
    var vector_mexico = new ol.layer.Vector({
      source: source,
      style: style_mexico
    });


    //Add all layers to the map
    var map = new ol.Map({
      layers: [raster, vector_world, vector_mexico],
      target: 'map',
      view: new ol.View({
        center: [0, 0],
        zoom: 1
      })
    });
<!DOCTYPE html>
<html>

<head>
  <title>TopoJSON</title>
  <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
  <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
  <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
  <script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>


</head>

<body>
  <div id="map" class="map"></div>

</body>

</html>

Upvotes: 1

Views: 602

Answers (1)

teknocreator
teknocreator

Reputation: 238

When you read in your features, you have to tell OL the projection of the data and then the projection you're displaying the features in. So, in this part of your code:

var features = (new ol.format.TopoJSON({
  layers: ['mexico']
})).readFeatures(mexicoData);

you will need to add this:

var features = (new ol.format.TopoJSON({
  layers: ['mexico']
})).readFeatures(mexicoData,{
  dataProjection: 'EPSG:4326',
  featureProjection: 'EPSG:3857'
});

I copied your source code and tried this out and it worked as expected. BTW, without this modification, your polygon does plot but it's REALLY small located at EPSG:3857 0,0 coordinates and you can see a small blue "dot" there. If you zoom in quite a lot, you'll see the outline of Mexico.

Upvotes: 1

Related Questions