diff --git a/.gitignore b/.gitignore index 3084355..a6a8a0d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ dist/ build/ *.pyc -mapbox_vector_tile.egg-info/ \ No newline at end of file +mapbox_vector_tile.egg-info/ +.idea/ diff --git a/.travis.yml b/.travis.yml index 7d69c5f..ca0bb23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,8 @@ python: install: - pip install flake8 - pip install coveralls -- python setup.py install +- pip install build +- python -m build script: - find mapbox_vector_tile tests -type f -name "*.py" -not -path "*/Mapbox/*" | xargs flake8 - coverage run --source=mapbox_vector_tile setup.py test diff --git a/README.md b/README.md index d3c35f9..5572d06 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,26 @@ Mapbox Vector Tile [![Build Status](https://travis-ci.org/tilezen/mapbox-vector-tile.svg?branch=master)](https://travis-ci.org/tilezen/mapbox-vector-tile) [![Coverage Status](https://coveralls.io/repos/github/tilezen/mapbox-vector-tile/badge.svg?branch=master)](https://coveralls.io/github/tilezen/mapbox-vector-tile?branch=master) + +## For compatibility with protobuf 4.21.1 +Regenerate the protobuf files from the protobuf definitions. + +Get the right version of protoc + +```bash +PB_REL="https://github.com/protocolbuffers/protobuf/releases" +curl -LO $PB_REL/download/v22.1/protoc-22.1-linux-x86_64.zip +unzip protoc-22.1-linux-x86_64.zip +``` + + +```bash +cd mapbox_vector_tile/Mapbox/proto +../../../bin/protoc --python_out=. vector_tile_p3.proto +mv vector_tile_p3_p2.py ../ +``` + + Installation ------------ @@ -20,7 +40,7 @@ Encoding Encode method expects an array of layers or atleast a single valid layer. A valid layer is a dictionary with the following keys -* `name`: layer name +* `name`: layer name * `features`: an array of features. A feature is a dictionary with the following keys: * `geometry`: representation of the feature geometry in WKT, WKB, or a shapely geometry. Coordinates are relative to the tile, scaled in the range `[0, 4096)`. See below for example code to perform the necessary transformation. *Note* that `GeometryCollection` types are not supported, and will trigger a `ValueError`. diff --git a/mapbox_vector_tile/Mapbox/vector_tile.proto b/mapbox_vector_tile/Mapbox/proto/vector_tile.proto similarity index 100% rename from mapbox_vector_tile/Mapbox/vector_tile.proto rename to mapbox_vector_tile/Mapbox/proto/vector_tile.proto diff --git a/mapbox_vector_tile/Mapbox/proto/vector_tile_p3.proto b/mapbox_vector_tile/Mapbox/proto/vector_tile_p3.proto new file mode 100644 index 0000000..3aaf9e2 --- /dev/null +++ b/mapbox_vector_tile/Mapbox/proto/vector_tile_p3.proto @@ -0,0 +1,94 @@ +// Protocol Version 1 + +syntax = "proto2"; + +package mapnik.vector; + +option optimize_for = LITE_RUNTIME; + +message tile { + enum GeomType { + Unknown = 0; + Point = 1; + LineString = 2; + Polygon = 3; + } + + // Variant type encoding + message value { + // Exactly one of these values may be present in a valid message + optional string string_value = 1; + optional float float_value = 2; + optional double double_value = 3; + optional int64 int_value = 4; + optional uint64 uint_value = 5; + optional sint64 sint_value = 6; + optional bool bool_value = 7; + + extensions 8 to max; + } + + message feature { + optional uint64 id = 1; + + // Tags of this feature. Even numbered values refer to the nth + // value in the keys list on the tile message, odd numbered + // values refer to the nth value in the values list on the tile + // message. + repeated uint32 tags = 2 [ packed = true ]; + + // The type of geometry stored in this feature. + optional GeomType type = 3 [ default = Unknown ]; + + // Contains a stream of commands and parameters (vertices). The + // repeat count is shifted to the left by 3 bits. This means + // that the command has 3 bits (0-7). The repeat count + // indicates how often this command is to be repeated. Defined + // commands are: + // - MoveTo: 1 (2 parameters follow) + // - LineTo: 2 (2 parameters follow) + // - ClosePath: 7 (no parameters follow) + // + // Ex.: MoveTo(3, 6), LineTo(8, 12), LineTo(20, 34), ClosePath + // Encoded as: [ 9 3 6 18 5 6 12 22 15 ] + // == command type 7 (ClosePath), length 1 + // ===== relative LineTo(+12, +22) == LineTo(20, 34) + // === relative LineTo(+5, +6) == LineTo(8, 12) + // == [00010 010] = command type 2 (LineTo), length 2 + // === relative MoveTo(+3, +6) + // == [00001 001] = command type 1 (MoveTo), length 1 + // Commands are encoded as uint32 varints, vertex parameters are + // encoded as sint32 varints (zigzag). Vertex parameters are + // also encoded as deltas to the previous position. The original + // position is (0,0) + repeated uint32 geometry = 4 [ packed = true ]; + } + + message layer { + // Any compliant implementation must first read the version + // number encoded in this message and choose the correct + // implementation for this version number before proceeding to + // decode other parts of this message. + required uint32 version = 15 [ default = 1 ]; + + required string name = 1; + + // The actual features in this tile. + repeated feature features = 2; + + // Dictionary encoding for keys + repeated string keys = 3; + + // Dictionary encoding for values + repeated value values = 4; + + // The bounding box in this tile spans from 0..4095 units + optional uint32 extent = 5 [ default = 4096 ]; + + extensions 16 to max; + } + + repeated layer layers = 3; + + extensions 16 to 8191; +} diff --git a/mapbox_vector_tile/Mapbox/vector_tile_p3_pb2.py b/mapbox_vector_tile/Mapbox/vector_tile_p3_pb2.py new file mode 100644 index 0000000..448c620 --- /dev/null +++ b/mapbox_vector_tile/Mapbox/vector_tile_p3_pb2.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: mapbox_vector_tile/Mapbox/proto/vector_tile_p3.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n4mapbox_vector_tile/Mapbox/proto/vector_tile_p3.proto\x12\rmapnik.vector\"\xc5\x04\n\x04tile\x12)\n\x06layers\x18\x03 \x03(\x0b\x32\x19.mapnik.vector.tile.layer\x1a\xa1\x01\n\x05value\x12\x14\n\x0cstring_value\x18\x01 \x01(\t\x12\x13\n\x0b\x66loat_value\x18\x02 \x01(\x02\x12\x14\n\x0c\x64ouble_value\x18\x03 \x01(\x01\x12\x11\n\tint_value\x18\x04 \x01(\x03\x12\x12\n\nuint_value\x18\x05 \x01(\x04\x12\x12\n\nsint_value\x18\x06 \x01(\x12\x12\x12\n\nbool_value\x18\x07 \x01(\x08*\x08\x08\x08\x10\x80\x80\x80\x80\x02\x1ar\n\x07\x66\x65\x61ture\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x10\n\x04tags\x18\x02 \x03(\rB\x02\x10\x01\x12\x33\n\x04type\x18\x03 \x01(\x0e\x32\x1c.mapnik.vector.tile.GeomType:\x07Unknown\x12\x14\n\x08geometry\x18\x04 \x03(\rB\x02\x10\x01\x1a\xb1\x01\n\x05layer\x12\x12\n\x07version\x18\x0f \x02(\r:\x01\x31\x12\x0c\n\x04name\x18\x01 \x02(\t\x12-\n\x08\x66\x65\x61tures\x18\x02 \x03(\x0b\x32\x1b.mapnik.vector.tile.feature\x12\x0c\n\x04keys\x18\x03 \x03(\t\x12)\n\x06values\x18\x04 \x03(\x0b\x32\x19.mapnik.vector.tile.value\x12\x14\n\x06\x65xtent\x18\x05 \x01(\r:\x04\x34\x30\x39\x36*\x08\x08\x10\x10\x80\x80\x80\x80\x02\"?\n\x08GeomType\x12\x0b\n\x07Unknown\x10\x00\x12\t\n\x05Point\x10\x01\x12\x0e\n\nLineString\x10\x02\x12\x0b\n\x07Polygon\x10\x03*\x05\x08\x10\x10\x80@B\x02H\x03') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'mapbox_vector_tile.Mapbox.proto.vector_tile_p3_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'H\003' + _TILE_FEATURE.fields_by_name['tags']._options = None + _TILE_FEATURE.fields_by_name['tags']._serialized_options = b'\020\001' + _TILE_FEATURE.fields_by_name['geometry']._options = None + _TILE_FEATURE.fields_by_name['geometry']._serialized_options = b'\020\001' + _globals['_TILE']._serialized_start=72 + _globals['_TILE']._serialized_end=653 + _globals['_TILE_VALUE']._serialized_start=124 + _globals['_TILE_VALUE']._serialized_end=285 + _globals['_TILE_FEATURE']._serialized_start=287 + _globals['_TILE_FEATURE']._serialized_end=401 + _globals['_TILE_LAYER']._serialized_start=404 + _globals['_TILE_LAYER']._serialized_end=581 + _globals['_TILE_GEOMTYPE']._serialized_start=583 + _globals['_TILE_GEOMTYPE']._serialized_end=646 +# @@protoc_insertion_point(module_scope) diff --git a/mapbox_vector_tile/Mapbox/vector_tile_pb2.py b/mapbox_vector_tile/Mapbox/vector_tile_pb2.py index 6c1bee2..ef5a0f9 100644 --- a/mapbox_vector_tile/Mapbox/vector_tile_pb2.py +++ b/mapbox_vector_tile/Mapbox/vector_tile_pb2.py @@ -1,19 +1,27 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! -# source: vector_tile.proto +# source: proto/vector_tile.proto +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) +_sym_db = _symbol_database.Default() + DESCRIPTOR = _descriptor.FileDescriptor( - name='vector_tile.proto', + name='proto/vector_tile.proto', package='mapnik.vector', - serialized_pb='\n\x11vector_tile.proto\x12\rmapnik.vector\"\xc5\x04\n\x04tile\x12)\n\x06layers\x18\x03 \x03(\x0b\x32\x19.mapnik.vector.tile.layer\x1a\xa1\x01\n\x05value\x12\x14\n\x0cstring_value\x18\x01 \x01(\t\x12\x13\n\x0b\x66loat_value\x18\x02 \x01(\x02\x12\x14\n\x0c\x64ouble_value\x18\x03 \x01(\x01\x12\x11\n\tint_value\x18\x04 \x01(\x03\x12\x12\n\nuint_value\x18\x05 \x01(\x04\x12\x12\n\nsint_value\x18\x06 \x01(\x12\x12\x12\n\nbool_value\x18\x07 \x01(\x08*\x08\x08\x08\x10\x80\x80\x80\x80\x02\x1ar\n\x07\x66\x65\x61ture\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x10\n\x04tags\x18\x02 \x03(\rB\x02\x10\x01\x12\x33\n\x04type\x18\x03 \x01(\x0e\x32\x1c.mapnik.vector.tile.GeomType:\x07Unknown\x12\x14\n\x08geometry\x18\x04 \x03(\rB\x02\x10\x01\x1a\xb1\x01\n\x05layer\x12\x12\n\x07version\x18\x0f \x02(\r:\x01\x31\x12\x0c\n\x04name\x18\x01 \x02(\t\x12-\n\x08\x66\x65\x61tures\x18\x02 \x03(\x0b\x32\x1b.mapnik.vector.tile.feature\x12\x0c\n\x04keys\x18\x03 \x03(\t\x12)\n\x06values\x18\x04 \x03(\x0b\x32\x19.mapnik.vector.tile.value\x12\x14\n\x06\x65xtent\x18\x05 \x01(\r:\x04\x34\x30\x39\x36*\x08\x08\x10\x10\x80\x80\x80\x80\x02\"?\n\x08GeomType\x12\x0b\n\x07Unknown\x10\x00\x12\t\n\x05Point\x10\x01\x12\x0e\n\nLineString\x10\x02\x12\x0b\n\x07Polygon\x10\x03*\x05\x08\x10\x10\x80@B\x02H\x03') + syntax='proto2', + serialized_pb=_b('\n\x17proto/vector_tile.proto\x12\rmapnik.vector\"\xc5\x04\n\x04tile\x12)\n\x06layers\x18\x03 \x03(\x0b\x32\x19.mapnik.vector.tile.layer\x1a\xa1\x01\n\x05value\x12\x14\n\x0cstring_value\x18\x01 \x01(\t\x12\x13\n\x0b\x66loat_value\x18\x02 \x01(\x02\x12\x14\n\x0c\x64ouble_value\x18\x03 \x01(\x01\x12\x11\n\tint_value\x18\x04 \x01(\x03\x12\x12\n\nuint_value\x18\x05 \x01(\x04\x12\x12\n\nsint_value\x18\x06 \x01(\x12\x12\x12\n\nbool_value\x18\x07 \x01(\x08*\x08\x08\x08\x10\x80\x80\x80\x80\x02\x1ar\n\x07\x66\x65\x61ture\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x10\n\x04tags\x18\x02 \x03(\rB\x02\x10\x01\x12\x33\n\x04type\x18\x03 \x01(\x0e\x32\x1c.mapnik.vector.tile.GeomType:\x07Unknown\x12\x14\n\x08geometry\x18\x04 \x03(\rB\x02\x10\x01\x1a\xb1\x01\n\x05layer\x12\x12\n\x07version\x18\x0f \x02(\r:\x01\x31\x12\x0c\n\x04name\x18\x01 \x02(\t\x12-\n\x08\x66\x65\x61tures\x18\x02 \x03(\x0b\x32\x1b.mapnik.vector.tile.feature\x12\x0c\n\x04keys\x18\x03 \x03(\t\x12)\n\x06values\x18\x04 \x03(\x0b\x32\x19.mapnik.vector.tile.value\x12\x14\n\x06\x65xtent\x18\x05 \x01(\r:\x04\x34\x30\x39\x36*\x08\x08\x10\x10\x80\x80\x80\x80\x02\"?\n\x08GeomType\x12\x0b\n\x07Unknown\x10\x00\x12\t\n\x05Point\x10\x01\x12\x0e\n\nLineString\x10\x02\x12\x0b\n\x07Polygon\x10\x03*\x05\x08\x10\x10\x80@B\x02H\x03') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -42,9 +50,10 @@ ], containing_type=None, options=None, - serialized_start=548, - serialized_end=611, + serialized_start=554, + serialized_end=617, ) +_sym_db.RegisterEnumDescriptor(_TILE_GEOMTYPE) _TILE_VALUE = _descriptor.Descriptor( @@ -57,21 +66,21 @@ _descriptor.FieldDescriptor( name='string_value', full_name='mapnik.vector.tile.value.string_value', index=0, number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), _descriptor.FieldDescriptor( name='float_value', full_name='mapnik.vector.tile.value.float_value', index=1, number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=0, + has_default_value=False, default_value=float(0), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), _descriptor.FieldDescriptor( name='double_value', full_name='mapnik.vector.tile.value.double_value', index=2, number=3, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=0, + has_default_value=False, default_value=float(0), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -111,9 +120,12 @@ ], options=None, is_extendable=True, + syntax='proto2', extension_ranges=[(8, 536870912), ], - serialized_start=89, - serialized_end=250, + oneofs=[ + ], + serialized_start=95, + serialized_end=256, ) _TILE_FEATURE = _descriptor.Descriptor( @@ -136,7 +148,7 @@ has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), '\020\001')), + options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))), _descriptor.FieldDescriptor( name='type', full_name='mapnik.vector.tile.feature.type', index=2, number=3, type=14, cpp_type=8, label=1, @@ -150,7 +162,7 @@ has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), '\020\001')), + options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))), ], extensions=[ ], @@ -159,9 +171,12 @@ ], options=None, is_extendable=False, + syntax='proto2', extension_ranges=[], - serialized_start=252, - serialized_end=366, + oneofs=[ + ], + serialized_start=258, + serialized_end=372, ) _TILE_LAYER = _descriptor.Descriptor( @@ -181,7 +196,7 @@ _descriptor.FieldDescriptor( name='name', full_name='mapnik.vector.tile.layer.name', index=1, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -221,9 +236,12 @@ ], options=None, is_extendable=True, + syntax='proto2', extension_ranges=[(16, 536870912), ], - serialized_start=369, - serialized_end=546, + oneofs=[ + ], + serialized_start=375, + serialized_end=552, ) _TILE = _descriptor.Descriptor( @@ -249,50 +267,60 @@ ], options=None, is_extendable=True, + syntax='proto2', extension_ranges=[(16, 8192), ], - serialized_start=37, - serialized_end=618, + oneofs=[ + ], + serialized_start=43, + serialized_end=624, ) -_TILE_VALUE.containing_type = _TILE; +_TILE_VALUE.containing_type = _TILE _TILE_FEATURE.fields_by_name['type'].enum_type = _TILE_GEOMTYPE -_TILE_FEATURE.containing_type = _TILE; +_TILE_FEATURE.containing_type = _TILE _TILE_LAYER.fields_by_name['features'].message_type = _TILE_FEATURE _TILE_LAYER.fields_by_name['values'].message_type = _TILE_VALUE -_TILE_LAYER.containing_type = _TILE; +_TILE_LAYER.containing_type = _TILE _TILE.fields_by_name['layers'].message_type = _TILE_LAYER -_TILE_GEOMTYPE.containing_type = _TILE; +_TILE_GEOMTYPE.containing_type = _TILE DESCRIPTOR.message_types_by_name['tile'] = _TILE -class tile(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - - class value(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _TILE_VALUE +tile = _reflection.GeneratedProtocolMessageType('tile', (_message.Message,), dict( + value = _reflection.GeneratedProtocolMessageType('value', (_message.Message,), dict( + DESCRIPTOR = _TILE_VALUE, + __module__ = 'proto.vector_tile_pb2' # @@protoc_insertion_point(class_scope:mapnik.vector.tile.value) + )) + , - class feature(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _TILE_FEATURE - + feature = _reflection.GeneratedProtocolMessageType('feature', (_message.Message,), dict( + DESCRIPTOR = _TILE_FEATURE, + __module__ = 'proto.vector_tile_pb2' # @@protoc_insertion_point(class_scope:mapnik.vector.tile.feature) + )) + , - class layer(_message.Message): - __metaclass__ = _reflection.GeneratedProtocolMessageType - DESCRIPTOR = _TILE_LAYER - + layer = _reflection.GeneratedProtocolMessageType('layer', (_message.Message,), dict( + DESCRIPTOR = _TILE_LAYER, + __module__ = 'proto.vector_tile_pb2' # @@protoc_insertion_point(class_scope:mapnik.vector.tile.layer) - DESCRIPTOR = _TILE - + )) + , + DESCRIPTOR = _TILE, + __module__ = 'proto.vector_tile_pb2' # @@protoc_insertion_point(class_scope:mapnik.vector.tile) + )) +_sym_db.RegisterMessage(tile) +_sym_db.RegisterMessage(tile.value) +_sym_db.RegisterMessage(tile.feature) +_sym_db.RegisterMessage(tile.layer) DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), 'H\003') +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('H\003')) _TILE_FEATURE.fields_by_name['tags'].has_options = True -_TILE_FEATURE.fields_by_name['tags']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), '\020\001') +_TILE_FEATURE.fields_by_name['tags']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')) _TILE_FEATURE.fields_by_name['geometry'].has_options = True -_TILE_FEATURE.fields_by_name['geometry']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), '\020\001') +_TILE_FEATURE.fields_by_name['geometry']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')) # @@protoc_insertion_point(module_scope) diff --git a/mapbox_vector_tile/Mapbox/vector_tile_pb2_p3.py b/mapbox_vector_tile/Mapbox/vector_tile_pb2_p3.py deleted file mode 100644 index 71ce6a3..0000000 --- a/mapbox_vector_tile/Mapbox/vector_tile_pb2_p3.py +++ /dev/null @@ -1,324 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: vector_tile.proto - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='vector_tile.proto', - package='mapnik.vector', - syntax='proto2', - serialized_pb=b'\n\x11vector_tile.proto\x12\rmapnik.vector\"\xc5\x04\n\x04tile\x12)\n\x06layers\x18\x03 \x03(\x0b\x32\x19.mapnik.vector.tile.layer\x1a\xa1\x01\n\x05value\x12\x14\n\x0cstring_value\x18\x01 \x01(\t\x12\x13\n\x0b\x66loat_value\x18\x02 \x01(\x02\x12\x14\n\x0c\x64ouble_value\x18\x03 \x01(\x01\x12\x11\n\tint_value\x18\x04 \x01(\x03\x12\x12\n\nuint_value\x18\x05 \x01(\x04\x12\x12\n\nsint_value\x18\x06 \x01(\x12\x12\x12\n\nbool_value\x18\x07 \x01(\x08*\x08\x08\x08\x10\x80\x80\x80\x80\x02\x1ar\n\x07\x66\x65\x61ture\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x10\n\x04tags\x18\x02 \x03(\rB\x02\x10\x01\x12\x33\n\x04type\x18\x03 \x01(\x0e\x32\x1c.mapnik.vector.tile.GeomType:\x07Unknown\x12\x14\n\x08geometry\x18\x04 \x03(\rB\x02\x10\x01\x1a\xb1\x01\n\x05layer\x12\x12\n\x07version\x18\x0f \x02(\r:\x01\x31\x12\x0c\n\x04name\x18\x01 \x02(\t\x12-\n\x08\x66\x65\x61tures\x18\x02 \x03(\x0b\x32\x1b.mapnik.vector.tile.feature\x12\x0c\n\x04keys\x18\x03 \x03(\t\x12)\n\x06values\x18\x04 \x03(\x0b\x32\x19.mapnik.vector.tile.value\x12\x14\n\x06\x65xtent\x18\x05 \x01(\r:\x04\x34\x30\x39\x36*\x08\x08\x10\x10\x80\x80\x80\x80\x02\"?\n\x08GeomType\x12\x0b\n\x07Unknown\x10\x00\x12\t\n\x05Point\x10\x01\x12\x0e\n\nLineString\x10\x02\x12\x0b\n\x07Polygon\x10\x03*\x05\x08\x10\x10\x80@B\x02H\x03' -) -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - - -_TILE_GEOMTYPE = _descriptor.EnumDescriptor( - name='GeomType', - full_name='mapnik.vector.tile.GeomType', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='Unknown', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='Point', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='LineString', index=2, number=2, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='Polygon', index=3, number=3, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=548, - serialized_end=611, -) -_sym_db.RegisterEnumDescriptor(_TILE_GEOMTYPE) - - -_TILE_VALUE = _descriptor.Descriptor( - name='value', - full_name='mapnik.vector.tile.value', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='string_value', full_name='mapnik.vector.tile.value.string_value', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='float_value', full_name='mapnik.vector.tile.value.float_value', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='double_value', full_name='mapnik.vector.tile.value.double_value', index=2, - number=3, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='int_value', full_name='mapnik.vector.tile.value.int_value', index=3, - number=4, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='uint_value', full_name='mapnik.vector.tile.value.uint_value', index=4, - number=5, type=4, cpp_type=4, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='sint_value', full_name='mapnik.vector.tile.value.sint_value', index=5, - number=6, type=18, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='bool_value', full_name='mapnik.vector.tile.value.bool_value', index=6, - number=7, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(8, 536870912), ], - oneofs=[ - ], - serialized_start=89, - serialized_end=250, -) - -_TILE_FEATURE = _descriptor.Descriptor( - name='feature', - full_name='mapnik.vector.tile.feature', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='id', full_name='mapnik.vector.tile.feature.id', index=0, - number=1, type=4, cpp_type=4, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='tags', full_name='mapnik.vector.tile.feature.tags', index=1, - number=2, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), b'\020\001')), - _descriptor.FieldDescriptor( - name='type', full_name='mapnik.vector.tile.feature.type', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='geometry', full_name='mapnik.vector.tile.feature.geometry', index=3, - number=4, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), b'\020\001')), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - serialized_start=252, - serialized_end=366, -) - -_TILE_LAYER = _descriptor.Descriptor( - name='layer', - full_name='mapnik.vector.tile.layer', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='version', full_name='mapnik.vector.tile.layer.version', index=0, - number=15, type=13, cpp_type=3, label=2, - has_default_value=True, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='name', full_name='mapnik.vector.tile.layer.name', index=1, - number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='features', full_name='mapnik.vector.tile.layer.features', index=2, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='keys', full_name='mapnik.vector.tile.layer.keys', index=3, - number=3, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='values', full_name='mapnik.vector.tile.layer.values', index=4, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='extent', full_name='mapnik.vector.tile.layer.extent', index=5, - number=5, type=13, cpp_type=3, label=1, - has_default_value=True, default_value=4096, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(16, 536870912), ], - oneofs=[ - ], - serialized_start=369, - serialized_end=546, -) - -_TILE = _descriptor.Descriptor( - name='tile', - full_name='mapnik.vector.tile', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='layers', full_name='mapnik.vector.tile.layers', index=0, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[_TILE_VALUE, _TILE_FEATURE, _TILE_LAYER, ], - enum_types=[ - _TILE_GEOMTYPE, - ], - options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(16, 8192), ], - oneofs=[ - ], - serialized_start=37, - serialized_end=618, -) - -_TILE_VALUE.containing_type = _TILE -_TILE_FEATURE.fields_by_name['type'].enum_type = _TILE_GEOMTYPE -_TILE_FEATURE.containing_type = _TILE -_TILE_LAYER.fields_by_name['features'].message_type = _TILE_FEATURE -_TILE_LAYER.fields_by_name['values'].message_type = _TILE_VALUE -_TILE_LAYER.containing_type = _TILE -_TILE.fields_by_name['layers'].message_type = _TILE_LAYER -_TILE_GEOMTYPE.containing_type = _TILE -DESCRIPTOR.message_types_by_name['tile'] = _TILE - -tile = _reflection.GeneratedProtocolMessageType('tile', (_message.Message,), dict( - - value = _reflection.GeneratedProtocolMessageType('value', (_message.Message,), dict( - DESCRIPTOR = _TILE_VALUE, - __module__ = 'vector_tile_pb2_p3' - # @@protoc_insertion_point(class_scope:mapnik.vector.tile.value) - )) - , - - feature = _reflection.GeneratedProtocolMessageType('feature', (_message.Message,), dict( - DESCRIPTOR = _TILE_FEATURE, - __module__ = 'vector_tile_pb2_p3' - # @@protoc_insertion_point(class_scope:mapnik.vector.tile.feature) - )) - , - - layer = _reflection.GeneratedProtocolMessageType('layer', (_message.Message,), dict( - DESCRIPTOR = _TILE_LAYER, - __module__ = 'vector_tile_pb2_p3' - # @@protoc_insertion_point(class_scope:mapnik.vector.tile.layer) - )) - , - DESCRIPTOR = _TILE, - __module__ = 'vector_tile_pb2_p3' - # @@protoc_insertion_point(class_scope:mapnik.vector.tile) - )) -_sym_db.RegisterMessage(tile) -_sym_db.RegisterMessage(tile.value) -_sym_db.RegisterMessage(tile.feature) -_sym_db.RegisterMessage(tile.layer) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), b'H\003') -_TILE_FEATURE.fields_by_name['tags'].has_options = True -_TILE_FEATURE.fields_by_name['tags']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), b'\020\001') -_TILE_FEATURE.fields_by_name['geometry'].has_options = True -_TILE_FEATURE.fields_by_name['geometry']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), b'\020\001') -# @@protoc_insertion_point(module_scope) diff --git a/mapbox_vector_tile/__init__.py b/mapbox_vector_tile/__init__.py index 8e045b3..3613291 100644 --- a/mapbox_vector_tile/__init__.py +++ b/mapbox_vector_tile/__init__.py @@ -12,12 +12,9 @@ def encode(layers, quantize_bounds=None, y_coord_down=False, extents=4096, on_invalid_geometry=None, round_fn=None, check_winding_order=True, max_geometry_validate_tries=5): - vector_tile = encoder.VectorTile( - extents, - on_invalid_geometry, - round_fn=round_fn, - check_winding_order=check_winding_order, - max_geometry_validate_tries=max_geometry_validate_tries) + vector_tile = encoder.VectorTile(extents, on_invalid_geometry, + round_fn=round_fn, + check_winding_order=check_winding_order) if (isinstance(layers, list)): for layer in layers: vector_tile.addFeatures(layer['features'], layer['name'], diff --git a/mapbox_vector_tile/compat.py b/mapbox_vector_tile/compat.py index 7abb584..54f2fbf 100644 --- a/mapbox_vector_tile/compat.py +++ b/mapbox_vector_tile/compat.py @@ -1,14 +1,5 @@ -import sys -from builtins import map - -PY3 = sys.version_info[0] == 3 - -if PY3: - from .Mapbox import vector_tile_pb2_p3 - vector_tile = vector_tile_pb2_p3 -else: - from .Mapbox import vector_tile_pb2 - vector_tile = vector_tile_pb2 +from .Mapbox import vector_tile_p3_pb2 +vector_tile = vector_tile_p3_pb2 def apply_map(fn, x): diff --git a/mapbox_vector_tile/decoder.py b/mapbox_vector_tile/decoder.py index 222e254..e42d2a7 100644 --- a/mapbox_vector_tile/decoder.py +++ b/mapbox_vector_tile/decoder.py @@ -1,4 +1,3 @@ -from past.builtins import xrange from .compat import vector_tile cmd_bits = 3 @@ -117,7 +116,7 @@ def _ensure_polygon_closed(coords): parts.append(coords) coords = [] - for point in xrange(0, cmd_len): + for point in range(0, cmd_len): x = geom[i] i = i + 1 diff --git a/mapbox_vector_tile/encoder.py b/mapbox_vector_tile/encoder.py index 12156c8..9323115 100644 --- a/mapbox_vector_tile/encoder.py +++ b/mapbox_vector_tile/encoder.py @@ -1,8 +1,5 @@ from mapbox_vector_tile.polygon import make_it_valid, clean_multi from numbers import Number -from past.builtins import long -from past.builtins import unicode -from past.builtins import xrange from shapely.geometry.base import BaseGeometry from shapely.geometry.multipolygon import MultiPolygon from shapely.geometry.polygon import orient @@ -12,7 +9,7 @@ from shapely.wkt import loads as load_wkt from shapely.validation import explain_validity import decimal -from .compat import PY3, vector_tile, apply_map +from .compat import vector_tile, apply_map from .geom_encoder import GeometryEncoder @@ -30,11 +27,11 @@ def on_invalid_geometry_make_valid(shape): def on_invalid_geometry_make_valid_and_clean(shape): shape = make_it_valid(shape, asserted=False) - if not shape.is_valid and shape.type == 'MultiPolygon': + if not shape.is_valid and shape.geom_type == 'MultiPolygon': shape = clean_multi(shape) assert shape.is_valid, \ "Not valid %s %s because %s" \ - % (shape.type, shape.wkt, explain_validity(shape)) + % (shape.geom_type, shape.wkt, explain_validity(shape)) return shape @@ -102,7 +99,7 @@ def addFeatures(self, features, layer_name='', self.addFeature(feature, shape, y_coord_down) def enforce_winding_order(self, shape, y_coord_down, n_try=1): - if shape.type == 'MultiPolygon': + if shape.geom_type == 'MultiPolygon': # If we are a multipolygon, we need to ensure that the # winding orders of the consituent polygons are # correct. In particular, the winding order of the @@ -113,7 +110,7 @@ def enforce_winding_order(self, shape, y_coord_down, n_try=1): shape = self.enforce_multipolygon_winding_order( shape, y_coord_down, n_try) - elif shape.type == 'Polygon': + elif shape.geom_type == 'Polygon': # Ensure that polygons are also oriented with the # appropriate winding order. Their exterior rings must # have a clockwise order, which is translated into a @@ -163,14 +160,14 @@ def handle_shape_validity(self, shape, y_coord_down, n_try): return shape def enforce_multipolygon_winding_order(self, shape, y_coord_down, n_try): - assert shape.type == 'MultiPolygon' + assert shape.geom_type == 'MultiPolygon' parts = [] for part in shape.geoms: part = self.enforce_polygon_winding_order( part, y_coord_down, n_try) if part is not None and not part.is_empty: - if part.type == 'MultiPolygon': + if part.geom_type == 'MultiPolygon': parts.extend(part.geoms) else: parts.append(part) @@ -188,7 +185,7 @@ def enforce_multipolygon_winding_order(self, shape, y_coord_down, n_try): return oriented_shape def enforce_polygon_winding_order(self, shape, y_coord_down, n_try): - assert shape.type == 'Polygon' + assert shape.geom_type == 'Polygon' def fn(point): x, y = point @@ -243,30 +240,30 @@ def addFeature(self, feature, shape, y_coord_down): f.geometry.extend(geometry) def _get_feature_type(self, shape): - if shape.type == 'Point' or shape.type == 'MultiPoint': + if shape.geom_type == 'Point' or shape.geom_type == 'MultiPoint': return self.tile.Point - elif shape.type == 'LineString' or shape.type == 'MultiLineString': + elif shape.geom_type == 'LineString' or shape.geom_type == 'MultiLineString': return self.tile.LineString - elif shape.type == 'Polygon' or shape.type == 'MultiPolygon': + elif shape.geom_type == 'Polygon' or shape.geom_type == 'MultiPolygon': return self.tile.Polygon - elif shape.type == 'GeometryCollection': + elif shape.geom_type == 'GeometryCollection': raise ValueError('Encoding geometry collections not supported') else: raise ValueError('Cannot encode unknown geometry type: %s' % - shape.type) + shape.geom_type) def _chunker(self, seq, size): - return [seq[pos:pos + size] for pos in xrange(0, len(seq), size)] + return [seq[pos:pos + size] for pos in range(0, len(seq), size)] def _can_handle_key(self, k): - return isinstance(k, (str, unicode)) + return isinstance(k, str) def _can_handle_val(self, v): - if isinstance(v, (str, unicode)): + if isinstance(v, str): return True elif isinstance(v, bool): return True - elif isinstance(v, (int, long)): + elif isinstance(v, int): return True elif isinstance(v, float): return True @@ -280,9 +277,6 @@ def _can_handle_attr(self, k, v): def _handle_attr(self, layer, feature, props): for k, v in props.items(): if self._can_handle_attr(k, v): - if not PY3 and isinstance(k, str): - k = k.decode('utf-8') - if k not in self.seen_keys_idx: layer.keys.append(k) self.seen_keys_idx[k] = self.key_idx @@ -298,13 +292,8 @@ def _handle_attr(self, layer, feature, props): if isinstance(v, bool): val.bool_value = v elif isinstance(v, str): - if PY3: - val.string_value = v - else: - val.string_value = unicode(v, 'utf-8') - elif isinstance(v, unicode): val.string_value = v - elif isinstance(v, (int, long)): + elif isinstance(v, int): val.int_value = v elif isinstance(v, float): val.double_value = v diff --git a/mapbox_vector_tile/geom_encoder.py b/mapbox_vector_tile/geom_encoder.py index c55bc74..d42de4a 100644 --- a/mapbox_vector_tile/geom_encoder.py +++ b/mapbox_vector_tile/geom_encoder.py @@ -52,8 +52,8 @@ def encode_multipoint(self, points): self._geometry = [cmd_move_to] last_x = 0 last_y = 0 - for float_x, float_y in points: - x, y = self.coords_on_grid(float_x, float_y) + for point in points: + x, y = self.coords_on_grid(point.x, point.y) dx, dy = x - last_x, y - last_y self._geometry.append(zigzag(dx)) self._geometry.append(zigzag(dy)) @@ -119,26 +119,26 @@ def encode_multipolygon(self, shape): self.encode_polygon(polygon) def encode(self, shape): - if shape.type == 'GeometryCollection': + if shape.geom_type == 'GeometryCollection': # do nothing pass - elif shape.type == 'Point': + elif shape.geom_type == 'Point': x, y = self.coords_on_grid(shape.x, shape.y) cmd_encoded = encode_cmd_length(CMD_MOVE_TO, 1) self._geometry = [cmd_encoded, zigzag(x), zigzag(y)] - elif shape.type == 'MultiPoint': + elif shape.geom_type == 'MultiPoint': self.encode_multipoint(shape.geoms) - elif shape.type == 'LineString': + elif shape.geom_type == 'LineString': coords = iter(shape.coords) self.encode_arc(coords) - elif shape.type == 'MultiLineString': + elif shape.geom_type == 'MultiLineString': self.encode_multilinestring(shape) - elif shape.type == 'Polygon': + elif shape.geom_type == 'Polygon': self.encode_polygon(shape) - elif shape.type == 'MultiPolygon': + elif shape.geom_type == 'MultiPolygon': self.encode_multipolygon(shape) else: - raise NotImplementedError("Can't do %s geometries" % shape.type) + raise NotImplementedError("Can't do %s geometries" % shape.geom_type) return self._geometry diff --git a/mapbox_vector_tile/polygon.py b/mapbox_vector_tile/polygon.py index 75d3ac7..28f632c 100644 --- a/mapbox_vector_tile/polygon.py +++ b/mapbox_vector_tile/polygon.py @@ -1,6 +1,6 @@ from shapely.geometry.multipolygon import MultiPolygon from shapely.geometry.polygon import Polygon -from shapely.ops import cascaded_union +from shapely.ops import unary_union from shapely.validation import explain_validity import pyclipper @@ -123,7 +123,7 @@ def _polytree_to_shapely(tree, asserted): # by the time recursion returns to the root. assert len(children) == 0 - union = cascaded_union(polygons) + union = unary_union(polygons) if asserted: assert union.is_valid return union @@ -193,7 +193,7 @@ def make_valid_multipolygon(shape, asserted): valid_g = make_valid_polygon(g, asserted) - if valid_g.type == 'MultiPolygon': + if valid_g.geom_type == 'MultiPolygon': new_g.extend(valid_g.geoms) else: new_g.append(valid_g) @@ -209,10 +209,10 @@ def make_it_valid(shape, asserted=True): if shape.is_empty: return shape - elif shape.type == 'MultiPolygon': + elif shape.geom_type == 'MultiPolygon': shape = make_valid_multipolygon(shape, asserted) - elif shape.type == 'Polygon': + elif shape.geom_type == 'Polygon': shape = make_valid_polygon(shape, asserted) return shape @@ -225,16 +225,16 @@ def clean_multi(shape): polygons = [] exterior_lines = [] interior_lines = [] - for p in shape: + for p in shape.geoms: exterior_lines = [] interior_lines = [] lnum = 0 boundary = p.boundary - if boundary.type == 'LineString': + if boundary.geom_type == 'LineString': if lnum == 0: exterior_lines.append(boundary) else: - for ls in boundary: + for ls in boundary.geoms: if lnum == 0: exterior_lines.append(ls) else: diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..74b48be --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,33 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "mapbox-vector-tile-mappy" +version = "1.0.15" +description = "Mapbox Vector Tile - Python library for encoding and decoding Mapbox vector tiles" +readme = "README.md" +classifiers = [ + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering :: GIS", +] +keywords = ["mapbox", "vector", "tile", "gis", "geospatial"] +authors = [{name = "Mappy Team", email = "dt.lbs.map@mappy.com"}] +license = "MIT" +urls = {Homepage = "http://fr.mappy.com/"} +requires-python = ">= 3.11" +dependencies = [ + "protobuf==4.21", + "shapely", + "pyclipper", + "setuptools>=80.9.0", + "wheel>=0.40.0", + "build>=1.0.0", + "twine>=4.0.0" +] + +[tool.setuptools.packages.find] +where = [""] +include = ["mapbox_vector_tile*"] +exclude = ["tests*"] + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b17a9cf --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +-e "." \ No newline at end of file diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 3480374..0000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[bdist_wheel] -universal=1 \ No newline at end of file diff --git a/setup.py b/setup.py index ed85460..1986725 100644 --- a/setup.py +++ b/setup.py @@ -15,25 +15,24 @@ def test_suite(): suite = unittest.TestLoader().discover("tests") return suite -setup(name='mapbox-vector-tile', - version='1.0.0', +# This setup.py is kept for backward compatibility +# The main configuration is now in pyproject.toml +setup(name='mapbox-vector-tile-mappy', + version='1.0.10', description=u"Mapbox Vector Tile", long_description=long_description, classifiers=[], keywords='', author=u"Harish Krishna", author_email='harish.krsn@gmail.com', - url='https://github.com/tilezen/mapbox-vector-tile', - license='MIT', packages=find_packages(), - include_package_data=True, + url='https://github.com/Mappy/mapbox-vector-tile', + license='MIT', zip_safe=False, - test_suite="setup.test_suite", + # test_suite="setup.test_suite", # Moved to pyproject.toml install_requires=[ - "setuptools", - "protobuf", - "shapely", - "future", - "pyclipper" + "protobuf>=3.20.3", + "shapely>=2.1.1", + "pyclipper>=1.3.0.post6" ] ) diff --git a/tests/test_decoder.py b/tests/test_decoder.py index 3521bae..9453e59 100644 --- a/tests/test_decoder.py +++ b/tests/test_decoder.py @@ -6,16 +6,12 @@ import unittest import mapbox_vector_tile -from mapbox_vector_tile.compat import PY3 class BaseTestCase(unittest.TestCase): def test_decoder(self): - if PY3: - vector_tile = b'\x1aI\n\x05water\x12\x1a\x08\x01\x12\x06\x00\x00\x01\x01\x02\x02\x18\x03"\x0c\t\x00\x80@\x1a\x00\x01\x02\x00\x00\x02\x0f\x1a\x03foo\x1a\x03baz\x1a\x03uid"\x05\n\x03bar"\x05\n\x03foo"\x02 {(\x80 x\x02' # noqa - else: - vector_tile = '\x1aI\n\x05water\x12\x1a\x08\x01\x12\x06\x00\x00\x01\x01\x02\x02\x18\x03"\x0c\t\x00\x80@\x1a\x00\x01\x02\x00\x00\x02\x0f\x1a\x03foo\x1a\x03baz\x1a\x03uid"\x05\n\x03bar"\x05\n\x03foo"\x02 {(\x80 x\x02' # noqa + vector_tile = b'\x1aI\n\x05water\x12\x1a\x08\x01\x12\x06\x00\x00\x01\x01\x02\x02\x18\x03"\x0c\t\x00\x80@\x1a\x00\x01\x02\x00\x00\x02\x0f\x1a\x03foo\x1a\x03baz\x1a\x03uid"\x05\n\x03bar"\x05\n\x03foo"\x02 {(\x80 x\x02' # noqa self.assertEqual(mapbox_vector_tile.decode(vector_tile), { 'water': { 'version': 2, @@ -38,10 +34,7 @@ def test_decode_polygon_no_cmd_seg_end(self): # CMD_SEG_END after the polygon parts # this tests that the decoder can detect that a new # CMD_MOVE_TO implicitly closes the previous polygon - if PY3: - vector_tile = b'\x1a+\n\x05water\x12\x1d\x18\x03"\x19\t\x00\x80@"\x08\x00\x00\x07\x07\x00\x00\x08\t\x02\x01"\x00\x03\x04\x00\x00\x04\x03\x00(\x80 x\x02' # noqa - else: - vector_tile = '\x1a+\n\x05water\x12\x1d\x18\x03"\x19\t\x00\x80@"\x08\x00\x00\x07\x07\x00\x00\x08\t\x02\x01"\x00\x03\x04\x00\x00\x04\x03\x00(\x80 x\x02' # noqa + vector_tile = b'\x1a+\n\x05water\x12\x1d\x18\x03"\x19\t\x00\x80@"\x08\x00\x00\x07\x07\x00\x00\x08\t\x02\x01"\x00\x03\x04\x00\x00\x04\x03\x00(\x80 x\x02' # noqa self.assertEqual(mapbox_vector_tile.decode(vector_tile), { 'water': { 'version': 2, @@ -59,10 +52,7 @@ def test_decode_polygon_no_cmd_seg_end(self): }) def test_nondefault_extent(self): - if PY3: - vector_tile = b'\x1aK\n\x05water\x12\x1c\x08\x01\x12\x06\x00\x00\x01\x01\x02\x02\x18\x02"\x0e\t\x80}\xd0\x12\x12\xbf>\xd86\xbf>\xd86\x1a\x03foo\x1a\x03baz\x1a\x03uid"\x05\n\x03bar"\x05\n\x03foo"\x02 {(\x80@x\x02' # noqa - else: - vector_tile = '\x1aK\n\x05water\x12\x1c\x08\x01\x12\x06\x00\x00\x01\x01\x02\x02\x18\x02"\x0e\t\x80}\xd0\x12\x12\xbf>\xd86\xbf>\xd86\x1a\x03foo\x1a\x03baz\x1a\x03uid"\x05\n\x03bar"\x05\n\x03foo"\x02 {(\x80@x\x02' # noqa + vector_tile = b'\x1aK\n\x05water\x12\x1c\x08\x01\x12\x06\x00\x00\x01\x01\x02\x02\x18\x02"\x0e\t\x80}\xd0\x12\x12\xbf>\xd86\xbf>\xd86\x1a\x03foo\x1a\x03baz\x1a\x03uid"\x05\n\x03bar"\x05\n\x03foo"\x02 {(\x80@x\x02' # noqa self.assertEqual(mapbox_vector_tile.decode(vector_tile), { 'water': { diff --git a/tests/test_encoder.py b/tests/test_encoder.py index 2198dd1..0da26b0 100644 --- a/tests/test_encoder.py +++ b/tests/test_encoder.py @@ -6,8 +6,6 @@ import mapbox_vector_tile from mapbox_vector_tile import encode, decode -from mapbox_vector_tile.compat import PY3 -from past.builtins import long, unicode from shapely import wkt @@ -141,14 +139,10 @@ def test_with_invalid_geometry(self): self.assertEqual(str(ex.exception), expected_result) def test_encode_unicode_property(self): - if PY3: - func = str - else: - func = unicode geometry = "LINESTRING(-71.160281 42.258729,-71.160837 43.259113,-71.161144 42.25932)" # noqa properties = { - "foo": func(self.feature_properties["foo"]), - "baz": func(self.feature_properties["baz"]), + "foo": str(self.feature_properties["foo"]), + "baz": str(self.feature_properties["baz"]), } self.assertRoundTrip( input_geometry=geometry, @@ -186,6 +180,14 @@ def test_encode_polygon_reverse_winding_order(self): input_geometry=geometry, expected_geometry=[[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]) + def test_encode_multipoint(self): + geometry = 'MULTIPOINT((10 10), (20 20), (10 40), (40 40), (30 30), (40 20), (30 10))' # noqa + self.assertRoundTrip(input_geometry=geometry, + expected_geometry=[ + [10, 10], [20, 20], [10, 40], + [40, 40], [30, 30], [40, 20], [30, 10], + ]) + def test_encode_multilinestring(self): geometry = 'MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))' # noqa self.assertRoundTrip(input_geometry=geometry, @@ -239,8 +241,7 @@ def test_encode_property_bool(self): def test_encode_property_long(self): geometry = 'POINT(0 0)' properties = { - 'test_int': int(1), - 'test_long': long(1) + 'test_int': int(1) } self.assertRoundTrip( input_geometry=geometry, @@ -498,12 +499,12 @@ def test_bowtie_self_crossing(self): total_area = 0 for g in valid_geometries: - self.assertEquals(1, len(g)) + self.assertEqual(1, len(g)) p = shapely.geometry.Polygon(g[0]) self.assertTrue(p.is_valid) self.assertGreater(p.area, 0) total_area += p.area - self.assertEquals(2, total_area) + self.assertEqual(2, total_area) def test_make_valid_self_crossing(self): from mapbox_vector_tile import encode @@ -549,7 +550,7 @@ def _multi(c): self.assertTrue(p.is_valid) self.assertGreater(p.area, 0) total_area += p.area - self.assertEquals(50, total_area) + self.assertEqual(50, total_area) def test_validate_generates_rounding_error(self): from mapbox_vector_tile import encode @@ -635,7 +636,7 @@ def test_make_valid_can_return_multipolygon(self): p = shapely.geometry.Polygon(poly[0], poly[1:]) self.assertTrue(p.is_valid) area += p.area - self.assertEquals(4339852.5, area) + self.assertEqual(4339852.5, area) def test_too_small_geometry(self): from mapbox_vector_tile import encode diff --git a/tests/test_polygon.py b/tests/test_polygon.py index 818b5e7..7465242 100644 --- a/tests/test_polygon.py +++ b/tests/test_polygon.py @@ -27,7 +27,7 @@ def test_multipolygon_with_flipped_ring(self): )""") fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(24, fixed.area) + self.assertEqual(24, fixed.area) def test_polygon_self_touching(self): geom = wkt.loads("""POLYGON( @@ -35,7 +35,7 @@ def test_polygon_self_touching(self): )""") fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(21, fixed.area) + self.assertEqual(21, fixed.area) def test_polygon_self_touching_inner(self): geom = wkt.loads("""POLYGON( @@ -44,7 +44,7 @@ def test_polygon_self_touching_inner(self): )""") fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(28, fixed.area) + self.assertEqual(28, fixed.area) def test_polygon_inners_touching(self): geom = wkt.loads("""POLYGON( @@ -54,7 +54,7 @@ def test_polygon_inners_touching(self): )""") fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(28, fixed.area) + self.assertEqual(28, fixed.area) def test_polygon_inner_touching_outer(self): geom = wkt.loads("""POLYGON( @@ -63,7 +63,7 @@ def test_polygon_inner_touching_outer(self): )""") fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(8, fixed.area) + self.assertEqual(8, fixed.area) def test_polygon_two_inners_touching_outer(self): geom = wkt.loads("""POLYGON( @@ -73,7 +73,7 @@ def test_polygon_two_inners_touching_outer(self): )""") fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(16, fixed.area) + self.assertEqual(16, fixed.area) def test_polygon_inners_touching_colinear(self): geom = wkt.loads("""POLYGON( @@ -84,7 +84,7 @@ def test_polygon_inners_touching_colinear(self): self.assertFalse(geom.is_valid) fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(26, fixed.area) + self.assertEqual(26, fixed.area) def test_polygon_inner_colinear_outer(self): geom = wkt.loads("""POLYGON( @@ -93,7 +93,7 @@ def test_polygon_inner_colinear_outer(self): )""") fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(7, fixed.area) + self.assertEqual(7, fixed.area) def test_polygon_many_inners_touching(self): geom = wkt.loads("""POLYGON( @@ -106,7 +106,7 @@ def test_polygon_many_inners_touching(self): self.assertFalse(geom.is_valid) fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(21, fixed.area) + self.assertEqual(21, fixed.area) def test_polygon_inner_spike(self): geom = wkt.loads("""POLYGON( @@ -116,7 +116,7 @@ def test_polygon_inner_spike(self): self.assertFalse(geom.is_valid) fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(10, fixed.area) + self.assertEqual(10, fixed.area) def test_polygon_disconnected_inner(self): geom = wkt.loads("""POLYGON( @@ -134,7 +134,7 @@ def test_polygon_disconnected_inner(self): self.assertFalse(geom.is_valid) fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(20.5, fixed.area) + self.assertEqual(20.5, fixed.area) def test_polygon_disconnected_outer(self): geom = wkt.loads("""POLYGON( @@ -144,7 +144,7 @@ def test_polygon_disconnected_outer(self): self.assertFalse(geom.is_valid) fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(9, fixed.area) + self.assertEqual(9, fixed.area) def test_polygon_ring_of_inners(self): geom = wkt.loads("""POLYGON( @@ -157,7 +157,7 @@ def test_polygon_ring_of_inners(self): self.assertFalse(geom.is_valid) fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(14, fixed.area) + self.assertEqual(14, fixed.area) def test_polygon_ring_of_inners_2(self): geom = wkt.loads("""POLYGON( @@ -172,7 +172,7 @@ def test_polygon_ring_of_inners_2(self): self.assertFalse(geom.is_valid) fixed = make_it_valid(geom) self.assertTrue(fixed.is_valid) - self.assertEquals(22, fixed.area) + self.assertEqual(22, fixed.area) def test_clean_multi(self): geom = wkt.loads("""MULTIPOLYGON (((1796 -189, 1794 -188, 1794 -190, 1798 -192,