automatically transform GeoJSON in WGS84 to webmercator

master
Oliver Tonnhofer 2013-12-02 14:13:31 +01:00
parent 804da8614b
commit e8f4098e18
4 changed files with 73 additions and 21 deletions

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"imposm3/geom/geos"
"imposm3/proj"
"io"
)
@ -39,6 +40,10 @@ func newPointFromCoords(coords []interface{}) (point, error) {
if !ok {
return p, errors.New("invalid lat")
}
if p.long >= -180.0 && p.long <= 180.0 && p.lat >= -90.0 && p.lat <= 90.0 {
p.long, p.lat = proj.WgsToMerc(p.long, p.lat)
}
return p, nil
}

View File

@ -7,7 +7,7 @@ import (
)
func TestParsePolygon(t *testing.T) {
r := bytes.NewBufferString(`{"type": "Polygon", "coordinates": [[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]}`)
r := bytes.NewBufferString(`{"type": "Polygon", "coordinates": [[[1000, 1000], [2000, 1000], [2000, 2000], [1000, 2000], [1000, 1000]]]}`)
geoms, err := ParseGeoJson(r)
if err != nil {
@ -18,12 +18,12 @@ func TestParsePolygon(t *testing.T) {
t.Fatal(geoms)
}
if math.Abs(geoms[0].Area()-100) > 0.00001 {
if math.Abs(geoms[0].Area()-1000000) > 0.00001 {
t.Fatal(geoms[0].Area())
}
// ignore z values
r = bytes.NewBufferString(`{"type": "Polygon", "coordinates": [[[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0], [0, 0, 0]]]}`)
r = bytes.NewBufferString(`{"type": "Polygon", "coordinates": [[[1000, 1000, 1000], [2000, 1000, 1000], [2000, 2000, 1000], [1000, 2000, 1000], [1000, 1000, 1000]]]}`)
geoms, err = ParseGeoJson(r)
if err != nil {
@ -34,11 +34,11 @@ func TestParsePolygon(t *testing.T) {
t.Fatal(geoms)
}
if math.Abs(geoms[0].Area()-100) > 0.00001 {
if math.Abs(geoms[0].Area()-1000000) > 0.00001 {
t.Fatal(geoms[0].Area())
}
r = bytes.NewBufferString(`{"type": "Polygon", "coordinates": [[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [[5, 5], [6, 5], [6, 6], [5, 6], [5, 5]]]}`)
r = bytes.NewBufferString(`{"type": "Polygon", "coordinates": [[[1000, 1000], [2000, 1000], [2000, 2000], [1000, 2000], [1000, 1000]], [[500, 500], [600, 500], [600, 600], [500, 600], [500, 500]]]}`)
geoms, err = ParseGeoJson(r)
if err != nil {
@ -49,7 +49,7 @@ func TestParsePolygon(t *testing.T) {
t.Fatal(geoms)
}
if math.Abs(geoms[0].Area()-99) > 0.00001 {
if math.Abs(geoms[0].Area()-990000) > 0.00001 {
t.Fatal(geoms[0].Area())
}
@ -57,8 +57,8 @@ func TestParsePolygon(t *testing.T) {
func TestParseMultiPolygon(t *testing.T) {
r := bytes.NewBufferString(`{"type": "MultiPolygon", "coordinates":
[[[[0, 0], [10, 0], [10, 10], [0, 0]]],
[[[0, 0], [10, 0], [10, 10], [0, 0]]]]
[[[[1000, 1000], [2000, 1000], [2000, 2000], [1000, 1000]]],
[[[1000, 1000], [2000, 1000], [2000, 2000], [1000, 1000]]]]
}`)
geoms, err := ParseGeoJson(r)
@ -73,7 +73,7 @@ func TestParseMultiPolygon(t *testing.T) {
func TestParseFeature(t *testing.T) {
r := bytes.NewBufferString(`{"type": "Feature", "geometry": {
"type": "Polygon", "coordinates": [[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]
"type": "Polygon", "coordinates": [[[1000, 1000], [2000, 1000], [2000, 2000], [1000, 2000], [1000, 1000]]]
}}`)
geoms, err := ParseGeoJson(r)
@ -84,7 +84,7 @@ func TestParseFeature(t *testing.T) {
if len(geoms) != 1 {
t.Fatal(geoms)
}
if math.Abs(geoms[0].Area()-100) > 0.00001 {
if math.Abs(geoms[0].Area()-1000000) > 0.00001 {
t.Fatal(geoms[0].Area())
}
}
@ -92,10 +92,10 @@ func TestParseFeature(t *testing.T) {
func TestParseFeatureCollection(t *testing.T) {
r := bytes.NewBufferString(`{"type": "FeatureCollection", "features": [
{"type": "Feature", "geometry":
{"type": "Polygon", "coordinates": [[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]}
{"type": "Polygon", "coordinates": [[[1000, 1000], [2000, 1000], [2000, 2000], [1000, 2000], [1000, 1000]]]}
},
{"type": "Feature", "geometry":
{"type": "Polygon", "coordinates": [[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]}
{"type": "Polygon", "coordinates": [[[1000, 1000], [2000, 1000], [2000, 2000], [1000, 2000], [1000, 1000]]]}
}
]}`)
geoms, err := ParseGeoJson(r)
@ -107,7 +107,54 @@ func TestParseFeatureCollection(t *testing.T) {
if len(geoms) != 2 {
t.Fatal(geoms)
}
if math.Abs(geoms[0].Area()-100) > 0.00001 {
if math.Abs(geoms[0].Area()-1000000) > 0.00001 {
t.Fatal(geoms[0].Area())
}
}
func TestParseGeoJson(t *testing.T) {
r := bytes.NewBufferString(`{"type": "FeatureCollection", "features": [
{"type": "Feature", "geometry":
{"type": "Polygon", "coordinates": [[[1000, 1000], [2000, 1000], [2000, 2000], [1000, 2000], [1000, 1000]]]}
},
{"type": "Feature", "geometry":
{"type": "Polygon", "coordinates": [[[1000, 1000], [2000, 1000], [2000, 2000], [1000, 2000], [1000, 1000]]]}
}
]}`)
geoms, err := ParseGeoJson(r)
if err != nil {
t.Fatal(err)
}
if len(geoms) != 2 {
t.Fatal(geoms)
}
if math.Abs(geoms[0].Area()-1000000) > 0.00001 {
t.Fatal(geoms[0].Area())
}
}
func TestParseGeoJsonTransform(t *testing.T) {
// automatically transforms WGS84 to webmercator
r := bytes.NewBufferString(`{"type": "FeatureCollection", "features": [
{"type": "Feature", "geometry":
{"type": "Polygon", "coordinates": [[[8, 53], [9, 53], [9, 54], [8, 54], [8, 53]]]}
},
{"type": "Feature", "geometry":
{"type": "Polygon", "coordinates": [[[9, 53], [10, 53], [10, 54], [9, 54], [9, 53]]]}
}
]}`)
geoms, err := ParseGeoJson(r)
if err != nil {
t.Fatal(err)
}
if len(geoms) != 2 {
t.Fatal(geoms)
}
if math.Abs(geoms[0].Area()-20834374847.98027) > 0.01 {
t.Fatal(geoms[0].Area())
}
}

View File

@ -7,13 +7,13 @@ import (
const pole = 6378137 * math.Pi // 20037508.342789244
func wgsToMerc(long, lat float64) (x, y float64) {
func WgsToMerc(long, lat float64) (x, y float64) {
x = long * pole / 180.0
y = math.Log(math.Tan((90.0+lat)*math.Pi/360.0)) / math.Pi * pole
return x, y
}
func mercToWgs(x, y float64) (long, lat float64) {
func MercToWgs(x, y float64) (long, lat float64) {
long = 180.0 * x / pole
lat = 180.0 / math.Pi * (2*math.Atan(math.Exp((y/pole)*math.Pi)) - math.Pi/2)
return long, lat
@ -21,10 +21,10 @@ func mercToWgs(x, y float64) (long, lat float64) {
func NodesToMerc(nodes []element.Node) {
for i, nd := range nodes {
nodes[i].Long, nodes[i].Lat = wgsToMerc(nd.Long, nd.Lat)
nodes[i].Long, nodes[i].Lat = WgsToMerc(nd.Long, nd.Lat)
}
}
func NodeToMerc(node *element.Node) {
node.Long, node.Lat = wgsToMerc(node.Long, node.Lat)
node.Long, node.Lat = WgsToMerc(node.Long, node.Lat)
}

View File

@ -6,23 +6,23 @@ import (
)
func TestWgsToMerc(t *testing.T) {
x, y := wgsToMerc(0, 0)
x, y := WgsToMerc(0, 0)
if x != 0 || y != 0 {
t.Fatalf("%v %v", x, y)
}
x, y = wgsToMerc(8, 53)
x, y = WgsToMerc(8, 53)
if math.Abs(x-890555.9263461898) > 1e-6 || math.Abs(y-6982997.920389788) > 1e-6 {
t.Fatalf("%v %v", x, y)
}
}
func TestMercToWgs(t *testing.T) {
long, lat := mercToWgs(0, 0)
long, lat := MercToWgs(0, 0)
if long != 0 || lat != 0 {
t.Fatalf("%v %v", long, lat)
}
long, lat = mercToWgs(890555.9263461898, 6982997.920389788)
long, lat = MercToWgs(890555.9263461898, 6982997.920389788)
if math.Abs(long-8) > 1e-6 || math.Abs(lat-53) > 1e-6 {
t.Fatalf("%v %v", long, lat)
}