add area and webmerc_area field; deprecate pseudoarea
parent
c9e5f22bb7
commit
9c86495275
|
@ -253,6 +253,15 @@ Like `geometry`, but the geometries will be validated and repaired when this tab
|
|||
|
||||
Area of polygon geometries in square meters. This area is calculated in the webmercator projection, so it is only accurate at the equator and gets off the more the geometry moves to the poles. It's still good enough to sort features by area for rendering purposes.
|
||||
|
||||
``area``
|
||||
^^^^^^^^
|
||||
|
||||
Area of polygon geometries in the unit of the selected projection (m² or degrees²). Note that a `meter` in the webmercator projection is only accurate at the equator and gets off the more the geometry moves to the poles. It's still good enough to sort features by area for rendering purposes.
|
||||
|
||||
``webmerc_area``
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Area of polygon geometries in m². This field only works for the webmercator projection (EPSG:3857). The latitude of the geometry is considered when calculating the area. This area is not precise, but a soccer field geometry at the equator should have roughly the same size as a soccer field in Svalbard.
|
||||
|
||||
``hstore_tags``
|
||||
^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -3,6 +3,7 @@ package mapping
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -34,7 +35,9 @@ func init() {
|
|||
"validated_geometry": {"validated_geometry", "validated_geometry", Geometry, nil, nil, false},
|
||||
"hstore_tags": {"hstore_tags", "hstore_string", HstoreString, nil, nil, false},
|
||||
"wayzorder": {"wayzorder", "int32", nil, MakeWayZOrder, nil, false},
|
||||
"pseudoarea": {"pseudoarea", "float32", PseudoArea, nil, nil, false},
|
||||
"pseudoarea": {"pseudoarea", "float32", nil, MakePseudoArea, nil, false},
|
||||
"area": {"area", "float32", Area, nil, nil, false},
|
||||
"webmerc_area": {"webmerc_area", "float32", WebmercArea, nil, nil, false},
|
||||
"zorder": {"zorder", "int32", nil, MakeZOrder, nil, false},
|
||||
"enumerate": {"enumerate", "int32", nil, MakeEnumerate, nil, false},
|
||||
"string_suffixreplace": {"string_suffixreplace", "string", nil, MakeSuffixReplace, nil, false},
|
||||
|
@ -213,7 +216,12 @@ func Geometry(val string, elem *element.OSMElem, geom *geom.Geometry, match Matc
|
|||
return string(geom.Wkb)
|
||||
}
|
||||
|
||||
func PseudoArea(val string, elem *element.OSMElem, geom *geom.Geometry, match Match) interface{} {
|
||||
func MakePseudoArea(fieldName string, fieldType FieldType, field Field) (MakeValue, error) {
|
||||
log.Print("warn: pseudoarea type is deprecated and will be removed. See area and webmercarea type.")
|
||||
return Area, nil
|
||||
}
|
||||
|
||||
func Area(val string, elem *element.OSMElem, geom *geom.Geometry, match Match) interface{} {
|
||||
area := geom.Geom.Area()
|
||||
if area == 0.0 {
|
||||
return nil
|
||||
|
@ -221,6 +229,23 @@ func PseudoArea(val string, elem *element.OSMElem, geom *geom.Geometry, match Ma
|
|||
return float32(area)
|
||||
}
|
||||
|
||||
func WebmercArea(val string, elem *element.OSMElem, geom *geom.Geometry, match Match) interface{} {
|
||||
area := geom.Geom.Area()
|
||||
if area == 0.0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
bounds := geom.Geom.Bounds()
|
||||
midY := bounds.MinY + (bounds.MaxY-bounds.MinY)/2
|
||||
|
||||
pole := 6378137 * math.Pi // 20037508.342789244
|
||||
midLat := 2*math.Atan(math.Exp((midY/pole)*math.Pi)) - math.Pi/2
|
||||
|
||||
area = area * math.Cos(midLat)
|
||||
|
||||
return float32(area)
|
||||
}
|
||||
|
||||
var hstoreReplacer = strings.NewReplacer("\\", "\\\\", "\"", "\\\"")
|
||||
|
||||
func HstoreString(val string, elem *element.OSMElem, geom *geom.Geometry, match Match) interface{} {
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/omniscale/imposm3/element"
|
||||
"github.com/omniscale/imposm3/geom"
|
||||
"github.com/omniscale/imposm3/geom/geos"
|
||||
)
|
||||
|
||||
func TestBool(t *testing.T) {
|
||||
|
@ -231,6 +233,39 @@ func TestWayZOrder(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAreaFields(t *testing.T) {
|
||||
tests := []struct {
|
||||
wkt string
|
||||
expected float32
|
||||
areaFunc MakeValue
|
||||
}{
|
||||
{"POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))", 100.0, Area},
|
||||
{"POLYGON((-10 0, 10 0, 10 10, -10 10, -10 0))", 200.0, Area},
|
||||
{"POLYGON((-10 -10, 10 -10, 10 10, -10 10, -10 -10))", 400.0, WebmercArea},
|
||||
{"POLYGON((1000000 2000000, 1001000 2000000, 1001000 2001000, 1000000 2001000, 1000000 2000000))", 1000000.0, Area},
|
||||
{"POLYGON((1000000 2000000, 1001000 2000000, 1001000 2001000, 1000000 2001000, 1000000 2000000))", 952750.625000, WebmercArea},
|
||||
{"POLYGON((1000000 5000000, 1001000 5000000, 1001000 5001000, 1000000 5001000, 1000000 5000000))", 755628.687500, WebmercArea},
|
||||
{"POLYGON((1000000 10000000, 1001000 10000000, 1001000 10001000, 1000000 10001000, 1000000 10000000))", 399584.031250, WebmercArea},
|
||||
}
|
||||
g := geos.NewGeos()
|
||||
for _, test := range tests {
|
||||
ggeom := g.FromWkt(test.wkt)
|
||||
if ggeom == nil {
|
||||
t.Fatalf("unable to create test geometry from %v", test.wkt)
|
||||
}
|
||||
geometry, err := geom.AsGeomElement(g, ggeom)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create test geometry %v: %v", test.wkt, err)
|
||||
}
|
||||
elem := &element.OSMElem{}
|
||||
match := Match{}
|
||||
|
||||
if v := test.areaFunc("", elem, &geometry, match); v.(float32) != test.expected {
|
||||
t.Errorf("%v %f != %f", test.wkt, v, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeSuffixReplace(t *testing.T) {
|
||||
field := Field{
|
||||
Name: "name", Key: "name", Type: "string_suffixreplace",
|
||||
|
|
|
@ -241,7 +241,7 @@ tables:
|
|||
- name: type
|
||||
type: mapping_value
|
||||
- name: area
|
||||
type: pseudoarea
|
||||
type: webmerc_area
|
||||
- args:
|
||||
values:
|
||||
- land
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
"key": null
|
||||
},
|
||||
{
|
||||
"type": "pseudoarea",
|
||||
"type": "webmerc_area",
|
||||
"name": "area",
|
||||
"key": null
|
||||
},
|
||||
|
@ -841,7 +841,7 @@
|
|||
"key": null
|
||||
},
|
||||
{
|
||||
"type": "pseudoarea",
|
||||
"type": "webmerc_area",
|
||||
"name": "area",
|
||||
"key": null
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue