简体   繁体   中英

Convert GeoJSON polygon to point before drawing in Leaflet Map

I have a GeoJSON dataset which has points and polygons. I have a simple Leaflet code which reads them into a map, like this:

var MyLayer = new L.GeoJSON.AJAX("/UrbanSyntax/Desarrollo/twitter    /data/boxtest.json", {

pointToLayer: function(feature, latlng) {      
return new L.CircleMarker(latlng, {
  radius: 3,
  fillOpacity: 0.75,
  color: getColor(feature.properties.created_at)
});
},
onEachFeature: function(feature, layer) {
layer.bindPopup(
  feature.properties.created_at + '<br />'
  + feature.geometry.coordinates + '<br />'
  + feature.properties.user  )
}
});

Most of the data are polygons, but I need to translate them to points (the polygon center) to simplify the map. I don't want to change the original GeoJSON when it's parsed since those polygons might be needed later.

I don't know where to "inject" code to read the polygon bounds, calculate a center and send a latlng to make a circlemarker. As it is now, the code reads the points and polygons in the json ok, but there are too many polygons in the data so the browser freezes. It works all right when I filter out the polys from the JSON and just map the points. I'm running out of ideas, and Leaflet documentation is so scarce in the JSON chapter... I just need a way to put an if in the pointToLayer code, separate the points from the polys, and map them all as points.

Thanks in advance!

Any ideas?

There does not appear to be a suitable hook.

At first glance, it seems that you might be able to mutate the GeoJSON that's passed to the style option's function, but Leaflet has already created its own feature/layer by that stage, so any mutation no effect.

To solve the problem, you could perform your own network request and modify the the data before it is passed in to the GeoJSON layer.

If you are targeting modern browsers, you could use fetch or one of its polyfills:

fetch('/UrbanSyntax/Desarrollo/twitter/data/boxtest.json')
.then(function (response) {
    return response.json();
})
.then(function (geoJson) {
  geoJson.features.forEach(function (feature) {
    if (feature.geometry.type === "Polygon") {
      // Copy the polygon geometry and replace it with a
      // point at the polygon's centroid.
      feature.polygonGeometry = feature.geometry;
      feature.geometry = {
        coordinates: getCentroid(feature.polygonGeometry),
        type: "Point"
      };
    }
  });
  geoJsonLayer = new L.GeoJSON(geoJson, {
    pointToLayer: function(feature, latlng) {      
      return new L.CircleMarker(latlng, {
        radius: 3,
        fillOpacity: 0.75,
        color: getColor(feature.properties.created_at)
      });
    },
    onEachFeature: function(feature, layer) {
      layer.bindPopup(
        feature.properties.created_at + '<br />'
        + feature.geometry.coordinates + '<br />'
        + feature.properties.user);
    }
  });
  geoJsonLayer.addTo(map);
});

Where getCentroid is some function that determines the centroid/center or whatever you wish to use.

This is the working code:

var myRequest = new Request('/UrbanSyntax/Desarrollo/twitter/data/boxtest.json');

fetch(myRequest).then(function(response) {
  return response.json().then(function(json) {

    json.features.forEach(function (feature) {
      if (feature.geometry.type === "Polygon") {

        feature.polygonGeometry = feature.geometry;

        var centroid = gju.rectangleCentroid(feature.geometry);

        feature.geometry = {
          coordinates: centroid.coordinates,
          type: "Point"
        };
      }
    });

    geoJsonLayer = new L.GeoJSON(json, {
      pointToLayer: function(feature, latlng) {      
        return new L.CircleMarker(latlng, {
          radius: 3,
          fillOpacity: 0.75,
          color: getColor(feature.properties.created_at)
        });
      },
      onEachFeature: function(feature, layer) {
        layer.bindPopup(
          feature.properties.created_at + '<br />'
          + feature.geometry.coordinates + '<br />'
          + feature.properties.user
        );
      }
    });

    geoJsonLayer.addTo(map);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM