From: Björn Harrtell Date: Fri, 10 Mar 2017 21:54:09 +0000 (+0000) Subject: Fix for incorrect scale/translate in ST_AsMVTGeom X-Git-Tag: 2.4.0alpha~157 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d263068755614662e454163e23e07844ccb7a3d5;p=postgis Fix for incorrect scale/translate in ST_AsMVTGeom git-svn-id: http://svn.osgeo.org/postgis/trunk@15326 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/postgis/mvt.c b/postgis/mvt.c index ee19248be..e38a39cec 100644 --- a/postgis/mvt.c +++ b/postgis/mvt.c @@ -444,55 +444,6 @@ static void parse_values(struct mvt_agg_context *ctx) ctx->feature->tags = tags; } -static void ptarray_mirror_y(POINTARRAY *pa, uint32_t extent) -{ - int i; - POINT2D *p; - - for (i = 0; i < pa->npoints; i++) { - p = (POINT2D *) getPoint_internal(pa, i); - p->y = extent - p->y; - } -} - -static void lwgeom_mirror_y(LWGEOM *in, uint32_t extent) -{ - LWCOLLECTION *col; - LWPOLY *poly; - int i; - - if ( (!in) || lwgeom_is_empty(in) ) return; - - switch (in->type) { - case POINTTYPE: - ptarray_mirror_y(lwgeom_as_lwpoint(in)->point, extent); - break; - case LINETYPE: - ptarray_mirror_y(lwgeom_as_lwline(in)->points, extent); - break; - case POLYGONTYPE: - poly = (LWPOLY *) in; - for (i=0; inrings; i++) - ptarray_mirror_y(poly->rings[i], extent); - break; - case MULTIPOINTTYPE: - case MULTILINETYPE: - case MULTIPOLYGONTYPE: - case COLLECTIONTYPE: - col = (LWCOLLECTION *) in; - for (i=0; ingeoms; i++) - lwgeom_mirror_y(col->geoms[i], extent); - break; - default: - lwerror("lwgeom_mirror_y: unsupported geometry type: %s", - lwtype_name(in->type)); - return; - } - - lwgeom_drop_bbox(in); - lwgeom_add_bbox(in); -} - /** * Transform a geometry into vector tile coordinate space. * @@ -506,6 +457,8 @@ LWGEOM *mvt_geom(LWGEOM *lwgeom, GBOX *gbox, uint32_t extent, uint32_t buffer, double height = gbox->ymax - gbox->ymin; double resx = width / extent; double resy = height / extent; + double fx = extent / width; + double fy = -(extent / height); if (width == 0 || height == 0) lwerror("mvt_geom: bounds width or height cannot be 0"); @@ -529,13 +482,15 @@ LWGEOM *mvt_geom(LWGEOM *lwgeom, GBOX *gbox, uint32_t extent, uint32_t buffer, #endif } - POINT4D factors; - factors.x = resx; - factors.y = resy; - factors.z = 1; - factors.m = 1; + AFFINE affine; + memset (&affine, 0, sizeof(affine)); + affine.afac = fx; + affine.efac = fy; + affine.ifac = 1; + affine.xoff = -gbox->xmin * fx; + affine.yoff = -gbox->ymax * fy; - lwgeom_scale(lwgeom, &factors); + lwgeom_affine(lwgeom, &affine); gridspec grid; memset(&grid, 0, sizeof(gridspec)); @@ -550,7 +505,6 @@ LWGEOM *mvt_geom(LWGEOM *lwgeom, GBOX *gbox, uint32_t extent, uint32_t buffer, lwgeom_out = lwgeom_grid(lwgeom_centroid(lwgeom), &grid); lwgeom_force_clockwise(lwgeom_out); - lwgeom_mirror_y(lwgeom_out, extent); lwgeom_out = lwgeom_make_valid(lwgeom_out); return lwgeom_out; diff --git a/regress/mvt.sql b/regress/mvt.sql index ffa22c800..f5a5fca34 100644 --- a/regress/mvt.sql +++ b/regress/mvt.sql @@ -17,7 +17,11 @@ select 'PG4', ST_AsText(ST_AsMVTGeom( 4096, 0, false)); select 'PG5', ST_AsText(ST_AsMVTGeom( ST_GeomFromText('POLYGON ((0 0, 10 0, 10 5, 0 -5, 0 0))'), - ST_MakeBox2D(ST_Point(0, 0), ST_Point(1, 1)), + ST_MakeBox2D(ST_Point(0, 0), ST_Point(4096*4096, 4096*4096)), + 4096, 0, false)); +select 'PG6', ST_AsText(ST_AsMVTGeom( + ST_GeomFromText('POLYGON ((762780 6474467, 717821 6797045, 1052826 6797045, 762780 6474467))'), + ST_MakeBox2D(ST_Point(626172.135625, 6261721.35625), ST_Point(1252344.27125, 6887893.49188)), 4096, 0, false)); -- geometry encoding tests diff --git a/regress/mvt_expected b/regress/mvt_expected index 2239f8629..97e843d9e 100644 --- a/regress/mvt_expected +++ b/regress/mvt_expected @@ -1,16 +1,17 @@ PG1|POINT(1 4094) -PG2|POINT(2 4092) -PG3|POINT(0 4095) +PG2|POINT(0 4095) +PG3|POINT(2 4092) PG4|MULTIPOLYGON(((5 4096,10 4096,10 4091,5 4096)),((0 4096,0 4101,5 4096,0 4096))) PG5|POINT(0 4096) +PG6|POLYGON((894 2704,2791 594,600 594,894 2704)) TG1|GiEKBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBKIAgeAI= TG2|GiMKBHRlc3QSDhICAAAYASIGETLePwIBGgJjMSICKAEogCB4Ag== TG3|GiYKBHRlc3QSERICAAAYAiIJCQCAQArQD88PGgJjMSICKAEogCB4Ag== TG4|GioKBHRlc3QSFRICAAAYAiINCQCAQBLoB+cH6AfnBxoCYzEiAigBKIAgeAI= TG5|GjgKBHRlc3QSIxICAAAYAiIbCQL+PxLoB+cH6AfnBwnND84PEugH5wfoB+cHGgJjMSICKAEogCB4 Ag== -TG6|GjIKBHRlc3QSHRICAAAYAyIVCUbsPxoxEwonPAkPCTEeEhQUCh0PGgJjMSICKAEogCB4Ag== -TG7|Gj0KBHRlc3QSKBICAAAYAyIgCVCwPxIKFDEdDwkAFCIyHh0eJwkAJw8JKBQSEwkAFA8aAmMxIgIo +TG6|GjIKBHRlc3QSHRICAAAYAyIVCUbsPxoURTsKCSgPCRQTEh4JCR4PGgJjMSICKAEogCB4Ag== +TG7|Gj0KBHRlc3QSKBICAAAYAyIgCVCwPxInCTIeDwkxCSITCgAoKAoeHQ8JHQASEwoAEw8aAmMxIgIo ASiAIHgC TG8|GiEKBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBKIAgeAI= TG9|GiMKBHRlc3QSDhICAAAYASIGETLeP2VGGgJjMSICKAEogCB4Ag==