mapbox / polylabel

A fast algorithm for finding the pole of inaccessibility of a polygon (in JavaScript and C++)
Other
1.44k stars 151 forks source link

Algorithm fails for some polygons #16

Closed andreynovikov closed 8 years ago

andreynovikov commented 8 years ago

Algorithm does not take into account segment endpoints. Look at this polygon: http://www.openstreetmap.org/way/300726657 As you see there are lines that are far from center but are considered very close to it, for instance one that is formed by http://www.openstreetmap.org/node/3048346767 and http://www.openstreetmap.org/node/3048346768

mourner commented 8 years ago

I didn't understand the issue. Can you please give an exact GeoJSON input of this polygon that I can test on?

andreynovikov commented 8 years ago

Sorry, may be I'm wrong with my assumption, I meant that distance is calculated not to line segment but to infinite line, defined by to points. May be I'm wrong, but for this polygon I get point in its upper right rectangle.

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": "way/300726657",
      "properties": {
        "addr:housenumber": 27,
        "addr:place": "Бутово парк",
        "addr:postcode": 142718,
        "amenity": "school",
        "building": "school"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              37.5904809,
              55.5434106
            ],
            [
              37.59043,
              55.5432862
            ],
            [
              37.59124,
              55.5431799
            ],
            [
              37.5914224,
              55.5436397
            ],
            [
              37.5916262,
              55.5436155
            ],
            [
              37.5917711,
              55.5439721
            ],
            [
              37.5914519,
              55.5440176
            ],
            [
              37.5913258,
              55.5437217
            ],
            [
              37.5901027,
              55.5438947
            ],
            [
              37.5900319,
              55.5437268
            ],
            [
              37.5901161,
              55.5437156
            ],
            [
              37.5900625,
              55.5436079
            ],
            [
              37.5911283,
              55.543455
            ],
            [
              37.591077,
              55.5433214
            ],
            [
              37.5904809,
              55.5434106
            ]
          ]
        ]
      }
    }
  ]
}
andreynovikov commented 8 years ago

Sorry again. It looks like I have incorrectly ported your algorithm to JTS. Some square distances are calculated incorrectly. This is strange because for most polygons it calculates correct point. Will look in my code more thoroughly.

mourner commented 8 years ago

Thanks!

andreynovikov commented 8 years ago

I have found where I was wrong. JTS geometries operate with geodetic coordinates, but the result is output in Mercator projection which has significant vertical distortion in our area. That's why visual result differed from mathematical computation. When I convert coordinates to Mercator I get expected results. But this adds lot of unneeded computations. As we do not need exact distances but only values to compare I've thought that I can apply scale factor (as stated in http://gis.stackexchange.com/a/110893/63896) just to square distance computation. But I failed to do it properly. Can you suggest where to apply it to get correct results?

mourner commented 8 years ago

@andreynovikov I believe you would need to scale all the coordinates in the input, then unscale the polylabel result.

andreynovikov commented 8 years ago

That's what I currently do. Hoped that there is a quicker solution. Anyway, thanks for brain-storming. :)