|
32 | 32 | "visible": lambda v: v.lower() == "true" |
33 | 33 | } |
34 | 34 |
|
| 35 | +GLOBAL_ATTRIBUTE_SERIALIZERS: Dict[str, Callable] = { |
| 36 | + "timestamp": lambda dt: datetime.strftime(dt, "%Y-%m-%dT%H:%M:%SZ"), |
| 37 | +} |
| 38 | + |
| 39 | + |
| 40 | +def _attributes_to_json(attributes: dict): |
| 41 | + def attr_serializer(k): |
| 42 | + return GLOBAL_ATTRIBUTE_SERIALIZERS.get(k, lambda v: v) |
| 43 | + return {k: attr_serializer(k)(v) for k, v in attributes.items()} |
| 44 | + |
35 | 45 |
|
36 | 46 | def is_valid_type( |
37 | 47 | element: Union["Area", "Node", "Relation", "Way"], |
@@ -334,6 +344,18 @@ def from_json(cls, data: dict, api: Optional[Overpass] = None) -> "Result": |
334 | 344 |
|
335 | 345 | return result |
336 | 346 |
|
| 347 | + def to_json(self) -> dict: |
| 348 | + def elements_to_json(): |
| 349 | + for elem_cls in [Node, Way, Relation, Area]: |
| 350 | + for element in self.get_elements(elem_cls): |
| 351 | + yield element.to_json() |
| 352 | + |
| 353 | + return { |
| 354 | + "version": 0.6, |
| 355 | + "generator": "Overpy Serializer", |
| 356 | + "elements": list(elements_to_json()) |
| 357 | + } |
| 358 | + |
337 | 359 | @classmethod |
338 | 360 | def from_xml( |
339 | 361 | cls, |
@@ -620,6 +642,11 @@ def from_json(cls: Type[ElementTypeVar], data: dict, result: Optional[Result] = |
620 | 642 | """ |
621 | 643 | raise NotImplementedError |
622 | 644 |
|
| 645 | + def to_json(self) -> dict: |
| 646 | + d = {"type": self._type_value, "id": self.id, "tags": self.tags} |
| 647 | + d.update(_attributes_to_json(self.attributes)) |
| 648 | + return d |
| 649 | + |
623 | 650 | @classmethod |
624 | 651 | def from_xml( |
625 | 652 | cls: Type[ElementTypeVar], |
@@ -782,6 +809,12 @@ def from_json(cls, data: dict, result: Optional[Result] = None) -> "Node": |
782 | 809 |
|
783 | 810 | return cls(node_id=node_id, lat=lat, lon=lon, tags=tags, attributes=attributes, result=result) |
784 | 811 |
|
| 812 | + def to_json(self) -> dict: |
| 813 | + d = super().to_json() |
| 814 | + d["lat"] = self.lat |
| 815 | + d["lon"] = self.lon |
| 816 | + return d |
| 817 | + |
785 | 818 | @classmethod |
786 | 819 | def from_xml(cls, child: xml.etree.ElementTree.Element, result: Optional[Result] = None) -> "Node": |
787 | 820 | """ |
@@ -965,6 +998,13 @@ def from_json(cls, data: dict, result: Optional[Result] = None) -> "Way": |
965 | 998 | way_id=way_id |
966 | 999 | ) |
967 | 1000 |
|
| 1001 | + def to_json(self) -> dict: |
| 1002 | + d = super().to_json() |
| 1003 | + if self.center_lat is not None and self.center_lon is not None: |
| 1004 | + d["center"] = {"lat": self.center_lat, "lon": self.center_lon} |
| 1005 | + d["nodes"] = self._node_ids |
| 1006 | + return d |
| 1007 | + |
968 | 1008 | @classmethod |
969 | 1009 | def from_xml(cls, child: xml.etree.ElementTree.Element, result: Optional[Result] = None) -> "Way": |
970 | 1010 | """ |
@@ -1104,6 +1144,14 @@ def from_json(cls, data: dict, result: Optional[Result] = None) -> "Relation": |
1104 | 1144 | result=result |
1105 | 1145 | ) |
1106 | 1146 |
|
| 1147 | + def to_json(self) -> dict: |
| 1148 | + d = super().to_json() |
| 1149 | + if self.center_lat is not None and self.center_lon is not None: |
| 1150 | + d["center"] = {"lat": self.center_lat, "lon": self.center_lon} |
| 1151 | + |
| 1152 | + d["members"] = [member.to_json() for member in self.members] |
| 1153 | + return d |
| 1154 | + |
1107 | 1155 | @classmethod |
1108 | 1156 | def from_xml(cls, child: xml.etree.ElementTree.Element, result: Optional[Result] = None) -> "Relation": |
1109 | 1157 | """ |
@@ -1244,6 +1292,13 @@ def from_json(cls, data: dict, result: Optional[Result] = None) -> "RelationMemb |
1244 | 1292 | result=result |
1245 | 1293 | ) |
1246 | 1294 |
|
| 1295 | + def to_json(self): |
| 1296 | + d = {"type": self._type_value, "ref": self.ref, "role": self.role} |
| 1297 | + if self.geometry is not None: |
| 1298 | + d["geometry"] = [{"lat": v.lat, "lon": v.lon} for v in self.geometry] |
| 1299 | + d.update(_attributes_to_json(self.attributes)) |
| 1300 | + return d |
| 1301 | + |
1247 | 1302 | @classmethod |
1248 | 1303 | def from_xml( |
1249 | 1304 | cls, |
|
0 commit comments