Skip to content

Commit

Permalink
geojson: Start with JSONToGeoJSONConverter
Browse files Browse the repository at this point in the history
  • Loading branch information
jarofgreen committed Oct 19, 2022
1 parent 69fc0ee commit 0dbb6b5
Show file tree
Hide file tree
Showing 11 changed files with 1,081 additions and 0 deletions.
134 changes: 134 additions & 0 deletions libcoveofds/lib/geojson.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import copy


class JSONToGeoJSONConverter:
def __init__(self):
self._nodes_geojson_features: list = []
self._links_geojson_features: list = []

def process_package(self, package_data: dict):
for network in package_data.get("networks", []):
self._process_network(network)

def _process_network(self, network_data: dict):
nodes = network_data.pop("nodes", [])
links = network_data.pop("links", [])
phases = network_data.pop("phases", [])
organisations = network_data.pop("organisations", [])

# Dereference `contracts.relatedPhases`
if "contracts" in network_data and isinstance(network_data["contracts"], list):
for contract in network_data["contracts"]:
if "relatedPhases" in contract and isinstance(
contract["relatedPhases"], list
):
contract["relatedPhases"] = [
self._dereference_object(phase, phases)
for phase in contract["relatedPhases"]
]

# Convert nodes to features
for node in nodes:
self._nodes_geojson_features.append(
self._convert_node_to_feature(node, network_data, organisations, phases)
)

# Convert links to features
for link in links:
self._links_geojson_features.append(
self._convert_link_to_feature(
link, network_data, organisations, phases, nodes
)
)

def get_nodes_geojson(self):
return {"type": "FeatureCollection", "features": self._nodes_geojson_features}

def get_links_geojson(self):
return {"type": "FeatureCollection", "features": self._links_geojson_features}

def _dereference_object(self, ref, list):
"""
Return from list the object referenced by ref. Otherwise, return ref.
"""

if "id" in ref:
for item in list:
if item.get("id") == ref["id"]:
return item

return ref

def _convert_node_to_feature(
self,
node_data: dict,
reduced_network_data: dict,
organisations: list,
phases: list,
):

reduced_node_data = copy.deepcopy(node_data)

feature = {"type": "Feature", "geometry": reduced_node_data.pop("location")}

# Dereference organisation references
for organisationReference in [
"physicalInfrastructureProvider",
"networkProvider",
]:
if organisationReference in reduced_node_data:
reduced_node_data[organisationReference] = self._dereference_object(
reduced_node_data[organisationReference], organisations
)

# Dereference phase references
if "phase" in reduced_node_data:
reduced_node_data["phase"] = self._dereference_object(
reduced_node_data["phase"], phases
)

feature["properties"] = reduced_node_data
feature["properties"]["network"] = reduced_network_data

return feature

def _convert_link_to_feature(
self,
link_data: dict,
reduced_network_data: dict,
organisations: list,
phases: list,
nodes: list,
):

reduced_link_data = copy.deepcopy(link_data)

feature = {"type": "Feature", "geometry": reduced_link_data.pop("route")}

# Dereference organisation references
for organisationReference in [
"physicalInfrastructureProvider",
"networkProvider",
]:
if organisationReference in reduced_link_data:
reduced_link_data[organisationReference] = self._dereference_object(
reduced_link_data[organisationReference], organisations
)

# Dereference phase references
if "phase" in reduced_link_data:
reduced_link_data["phase"] = self._dereference_object(
reduced_link_data["phase"], phases
)

# Dereference endpoints
for endpoint in ["start", "end"]:
if endpoint in reduced_link_data:
for node in nodes:
if "id" in node and node["id"] == reduced_link_data[endpoint]:
reduced_link_data[endpoint] = node

feature["properties"] = reduced_link_data
feature["properties"]["network"] = reduced_network_data

return feature
96 changes: 96 additions & 0 deletions tests/fixtures/json_to_geojson/basic_1.expected.links.geo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-0.173,
5.626
],
[
-0.178,
5.807
],
[
-0.112,
5.971
],
[
-0.211,
5.963
],
[
-0.321,
6.17
],
[
-0.488,
6.29
],
[
-0.56,
6.421
],
[
-0.752,
6.533
],
[
-0.867,
6.607
],
[
-1.101,
6.585
],
[
-1.304,
6.623
],
[
-1.461,
6.727
],
[
-1.628,
6.713
]
]
},
"properties": {
"id": "1",
"name": "Accra to Kumasi",
"start": {
"id": "1",
"name": "Accra",
"location": {
"type": "Point",
"coordinates": [
-0.174,
5.625
]
}
},
"end": {
"id": "2",
"name": "Kumasi",
"status": "operational",
"location": {
"type": "Point",
"coordinates": [
-1.628,
6.711
]
}
},
"network": {
"id": "a096d627-72e1-4f9b-b129-951b1737bff4",
"name": "Ghana Fibre Network"
}
}
}
]
}
42 changes: 42 additions & 0 deletions tests/fixtures/json_to_geojson/basic_1.expected.nodes.geo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-0.174,
5.625
]
},
"properties": {
"id": "1",
"name": "Accra",
"network": {
"id": "a096d627-72e1-4f9b-b129-951b1737bff4",
"name": "Ghana Fibre Network"
}
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-1.628,
6.711
]
},
"properties": {
"id": "2",
"name": "Kumasi",
"status": "operational",
"network": {
"id": "a096d627-72e1-4f9b-b129-951b1737bff4",
"name": "Ghana Fibre Network"
}
}
}
]
}
98 changes: 98 additions & 0 deletions tests/fixtures/json_to_geojson/basic_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"networks": [
{
"id": "a096d627-72e1-4f9b-b129-951b1737bff4",
"name": "Ghana Fibre Network",
"nodes": [
{
"id": "1",
"name": "Accra",
"location": {
"type": "Point",
"coordinates": [
-0.174,
5.625
]
}
},
{
"id": "2",
"name": "Kumasi",
"status": "operational",
"location": {
"type": "Point",
"coordinates": [
-1.628,
6.711
]
}
}
],
"links": [
{
"id": "1",
"name": "Accra to Kumasi",
"start": "1",
"end": "2",
"route": {
"type": "LineString",
"coordinates": [
[
-0.173,
5.626
],
[
-0.178,
5.807
],
[
-0.112,
5.971
],
[
-0.211,
5.963
],
[
-0.321,
6.170
],
[
-0.488,
6.290
],
[
-0.560,
6.421
],
[
-0.752,
6.533
],
[
-0.867,
6.607
],
[
-1.101,
6.585
],
[
-1.304,
6.623
],
[
-1.461,
6.727
],
[
-1.628,
6.713
]
]
}
}
]
}
]
}
Loading

0 comments on commit 0dbb6b5

Please sign in to comment.