]> granicus.if.org Git - postgis/commitdiff
Improved integer encoding for ST_AsMVT
authorBjörn Harrtell <bjorn@wololo.org>
Sun, 26 Feb 2017 16:42:56 +0000 (16:42 +0000)
committerBjörn Harrtell <bjorn@wololo.org>
Sun, 26 Feb 2017 16:42:56 +0000 (16:42 +0000)
Closes #3714

git-svn-id: http://svn.osgeo.org/postgis/trunk@15316 b70326c6-7e19-0410-871a-916f4a2858ee

postgis/mvt.c
regress/mvt.sql
regress/mvt_expected

index 08beb0d52098923872375226b6b0b2e5dfd1022a..8c077f83be9a427810fbcf7aa3496846374c1119 100644 (file)
@@ -60,12 +60,6 @@ struct mvt_kv_double_value {
        UT_hash_handle hh;
 };
 
-struct mvt_kv_int_value {
-       int64_t int_value;
-       uint32_t id;
-       UT_hash_handle hh;
-};
-
 struct mvt_kv_uint_value {
        uint64_t uint_value;
        uint32_t id;
@@ -405,8 +399,6 @@ static void encode_values(struct mvt_agg_context *ctx)
                float_values_hash, has_float_value, float_value);
        MVT_CREATE_VALUES(mvt_kv_double_value,
                double_values_hash, has_double_value, double_value);
-       MVT_CREATE_VALUES(mvt_kv_int_value,
-               int_values_hash, has_int_value, int_value);
        MVT_CREATE_VALUES(mvt_kv_uint_value,
                uint_values_hash, has_uint_value, uint_value);
        MVT_CREATE_VALUES(mvt_kv_sint_value,
@@ -418,11 +410,9 @@ static void encode_values(struct mvt_agg_context *ctx)
        ctx->layer->values = values;
 }
 
-
-#define MVT_PARSE_VALUE(type, kvtype, hash, valuefield, datumfunc, size) \
+#define MVT_PARSE_VALUE(value, kvtype, hash, valuefield, size) \
 { \
        struct kvtype *kv; \
-       type value = datumfunc(datum); \
        HASH_FIND(hh, ctx->hash, &value, size, kv); \
        if (!kv) { \
                kv = palloc(sizeof(*kv)); \
@@ -434,6 +424,26 @@ static void encode_values(struct mvt_agg_context *ctx)
        tags[c*2+1] = kv->id; \
 }
 
+#define MVT_PARSE_DATUM(type, kvtype, hash, valuefield, datumfunc, size) \
+{ \
+       type value = datumfunc(datum); \
+       MVT_PARSE_VALUE(value, kvtype, hash, valuefield, size); \
+}
+
+#define MVT_PARSE_INT_DATUM(type, datumfunc) \
+{ \
+       type value = datumfunc(datum); \
+       if (value >= 0) { \
+               MVT_PARSE_VALUE(value, mvt_kv_uint_value, \
+                               uint_values_hash, uint_value, \
+                               sizeof(uint64_t)) \
+       } else { \
+               MVT_PARSE_VALUE(value, mvt_kv_sint_value, \
+                               sint_values_hash, sint_value, \
+                               sizeof(int64_t)) \
+       } \
+}
+
 static void parse_value_as_string(struct mvt_agg_context *ctx, Oid typoid,
                Datum datum, uint32_t *tags, uint32_t c, uint32_t k) {
        struct mvt_kv_string_value *kv;
@@ -472,37 +482,31 @@ static void parse_values(struct mvt_agg_context *ctx)
                Oid typoid = getBaseType(tupdesc->attrs[i]->atttypid);
                switch (typoid) {
                case BOOLOID:
-                       MVT_PARSE_VALUE(bool, mvt_kv_bool_value,
+                       MVT_PARSE_DATUM(bool, mvt_kv_bool_value,
                                bool_values_hash, bool_value,
                                DatumGetBool, sizeof(bool));
                        break;
                case INT2OID:
-                       MVT_PARSE_VALUE(int16_t, mvt_kv_int_value,
-                               int_values_hash, int_value,
-                               DatumGetInt16, sizeof(int64_t));
+                       MVT_PARSE_INT_DATUM(int16_t, DatumGetInt16);
                        break;
                case INT4OID:
-                       MVT_PARSE_VALUE(int32_t, mvt_kv_int_value,
-                               int_values_hash, int_value,
-                               DatumGetInt32, sizeof(int64_t));
+                       MVT_PARSE_INT_DATUM(int32_t, DatumGetInt32);
                        break;
                case INT8OID:
-                       MVT_PARSE_VALUE(int64_t, mvt_kv_int_value,
-                               int_values_hash, int_value,
-                               DatumGetInt64, sizeof(int64_t));
+                       MVT_PARSE_INT_DATUM(int64_t, DatumGetInt64);
                        break;
                case FLOAT4OID:
-                       MVT_PARSE_VALUE(float, mvt_kv_float_value,
+                       MVT_PARSE_DATUM(float, mvt_kv_float_value,
                                float_values_hash, float_value,
                                DatumGetFloat4, sizeof(float));
                        break;
                case FLOAT8OID:
-                       MVT_PARSE_VALUE(double, mvt_kv_double_value,
+                       MVT_PARSE_DATUM(double, mvt_kv_double_value,
                                double_values_hash, double_value,
                                DatumGetFloat8, sizeof(double));
                        break;
                case TEXTOID:
-                       MVT_PARSE_VALUE(char *, mvt_kv_string_value,
+                       MVT_PARSE_DATUM(char *, mvt_kv_string_value,
                                string_values_hash, string_value,
                                TextDatumGetCString, strlen(value));
                        break;
index d6606877f6dd643a7fb1a9f17fe5d5177ce17bea..d892b8014b1d610b33cb9f54a5e63d08a8d6cf2d 100644 (file)
@@ -58,6 +58,10 @@ SELECT 'TA4', encode(ST_AsMVT('test',
 SELECT 'TA5', encode(ST_AsMVT('test',
     ST_MakeBox2D(ST_Point(0, 0), ST_Point(4096, 4096)), 4096, 0, false, 'geom', q
 ), 'base64') FROM (SELECT ST_GeomFromText('POINT(25 17)') AS geom, 1 AS c1, 'abcd'::text AS c2) AS q;
+SELECT 'TA6', encode(ST_AsMVT('test',
+    ST_MakeBox2D(ST_Point(0, 0), ST_Point(4096, 4096)), 4096, 0, false, 'geom', q
+), 'base64') FROM (SELECT 1 AS c1, -1 AS c2,
+    ST_GeomFromText('POINT(25 17)') AS geom) AS q;
 
 -- unsupported input
 SELECT 'TU1';
index 110baa1ccd0f394c5b0db91dbf4760de6bb2e032..56f1ba298bebab8d819541a14013557a1da306ca 100644 (file)
@@ -1,18 +1,19 @@
-TG1|Gh4KBHRlc3QSDBICAAAYASIECTLePxoCYzEiAiABeAI=
-TG2|Gh4KBHRlc3QSDBICAAAYASIECTLePxoCYzEiAiABeAI=
-TG3|GiMKBHRlc3QSERICAAAYAiIJCQCAQArQD88PGgJjMSICIAF4Ag==
-TG4|GicKBHRlc3QSFRICAAAYAiINCQCAQBLoB+cH6AfnBxoCYzEiAiABeAI=
-TG5|GjUKBHRlc3QSIxICAAAYAiIbCQL+PxLoB+cH6AfnBwnND84PEugH5wfoB+cHGgJjMSICIAF4Ag==
-TG6|GjMKBHRlc3QSIRICAAAYAyIZCUbsPyIURTsKCSgyFA8JHScaHgkJHhMTDxoCYzEiAiABeAI=
+TG1|Gh4KBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBeAI=
+TG2|Gh4KBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBeAI=
+TG3|GiMKBHRlc3QSERICAAAYAiIJCQCAQArQD88PGgJjMSICKAF4Ag==
+TG4|GicKBHRlc3QSFRICAAAYAiINCQCAQBLoB+cH6AfnBxoCYzEiAigBeAI=
+TG5|GjUKBHRlc3QSIxICAAAYAiIbCQL+PxLoB+cH6AfnBwnND84PEugH5wfoB+cHGgJjMSICKAF4Ag==
+TG6|GjMKBHRlc3QSIRICAAAYAyIZCUbsPyIURTsKCSgyFA8JHScaHgkJHhMTDxoCYzEiAigBeAI=
 TG7|Gj0KBHRlc3QSKxICAAAYAyIjCVCwPxonCTIeCRMJJwoqEwoAKCgKHh0xHQkUHhoTCgATFAoaAmMx
-IgIgAXgC
-TG8|Gh4KBHRlc3QSDBICAAAYASIECTLePxoCYzEiAiABeAI=
-TG9|Gh4KBHRlc3QSDBICAAAYASIECTLePxoCYzEiAiABeAI=
-TA1|GiwKBHRlc3QSDhIEAAABARgBIgQJMt4/GgJjMRoCYzIiAiABIgYKBGFiY2R4Ag==
+IgIoAXgC
+TG8|Gh4KBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBeAI=
+TG9|Gh4KBHRlc3QSDBICAAAYASIECTLePxoCYzEiAigBeAI=
+TA1|GiwKBHRlc3QSDhIEAAABARgBIgQJMt4/GgJjMRoCYzIiAigBIgYKBGFiY2R4Ag==
 TA2|GiUKBHRlc3QSDBICAAAYASIECTLePxoCYzEiCRmamZmZmZnxP3gC
 TA3|GhYKBHRlc3QSCBgBIgQJMt4/GgJjMXgC
-TA4|GjAKBHRlc3QSDBICAAAYASIECTLePxIMEgIAARgBIgQJMt4/GgJjMSICIAEiAiACeAI=
-TA5|GiwKBHRlc3QSDhIEAAABARgBIgQJMt4/GgJjMRoCYzIiAiABIgYKBGFiY2R4Ag==
+TA4|GjAKBHRlc3QSDBICAAAYASIECTLePxIMEgIAARgBIgQJMt4/GgJjMSICKAEiAigCeAI=
+TA5|GiwKBHRlc3QSDhIEAAABARgBIgQJMt4/GgJjMRoCYzIiAigBIgYKBGFiY2R4Ag==
+TA6|GigKBHRlc3QSDhIEAAABARgBIgQJMt4/GgJjMRoCYzIiAigBIgIwAXgC
 TU1
 ERROR:  could not determine polymorphic type because input has type "unknown"
 TU2