Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data structure #89

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions osm2gtfs/core/debug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# coding=utf-8


class Debug(object):
"""The Debug class contains special functions used for debugging

"""

@staticmethod
def print_shape_for_leaflet(shape):
print "var shape = [",
i = 0
for node in shape:
print "new L.LatLng(" + str(node["lat"]) + ", " + str(node["lon"]) + ")",
if i != len(shape) - 1:
print ",",
i += 1
print "];"
i = 0
for node in shape:
print "L.marker([" + str(node["lat"]) + ", " + str(node["lon"]) + "]).addTo(map)"
print " .bindPopup(\"" + str(i) + "\").openPopup();"
i += 1
227 changes: 171 additions & 56 deletions osm2gtfs/core/osm_connector.py

Large diffs are not rendered by default.

109 changes: 0 additions & 109 deletions osm2gtfs/core/osm_routes.py

This file was deleted.

76 changes: 0 additions & 76 deletions osm2gtfs/core/osm_stops.py

This file was deleted.

82 changes: 82 additions & 0 deletions osm2gtfs/core/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# coding=utf-8

import attr


@attr.s
class Line(object):
"""A general public transport service Line.

It's a container of meta information and different Itinerary objects for
variants of the same service line.

In OpenStreetMap this is usually represented as "route_master" relation.
In GTFS this is usually represented as "route"

"""
osm_id = attr.ib()
route_id = attr.ib()
name = attr.ib()
route_type = attr.ib() # Required (Tram, Subway, Rail, Bus, ...)

route_desc = attr.ib(default=None)
route_url = attr.ib(default=None)
route_color = attr.ib(default="FFFFFF")
route_text_color = attr.ib(default="000000")
osm_url = attr.ib(default="http://osm.org/relation/" + str(osm_id))
frequency = attr.ib(default=None)

# Related route variants
_itineraries = attr.ib(default=attr.Factory(list))

def add_itinerary(self, itinerary):
if self.route_id.encode('utf-8') != itinerary.route_id.encode('utf-8'):
raise ValueError('Itinerary route ID (' +
itinerary.route_id +
') does not match Line route ID (' +
self.route_id + ')')
self._itineraries.append(itinerary)

def get_itineraries(self):
return self._itineraries


@attr.s
class Itinerary(object):
"""A public transport service itinerary.

It's a representation of a possible variant of a line, grouped together by
a Line object.

In OpenStreetMap this is usually represented as "route" relation.
In GTFS this is not exlicitly presented but used as based to create "trips"

"""
osm_id = attr.ib()
route_id = attr.ib()
name = attr.ib()
fr = attr.ib()
to = attr.ib()
shape = attr.ib()
stops = attr.ib()
travel_time = attr.ib()

route_url = attr.ib(default=None)
wheelchair_accessible = attr.ib(default=0)
bikes_allowed = attr.ib(default=0)
osm_url = attr.ib(default="http://osm.org/relation/" + str(osm_id))

# Useful information for further calculation
duration = attr.ib(default=None)

# All stop objects of itinerary
_stop_objects = attr.ib(default=attr.Factory(list))

def add_stop(self, stop):
self._stop_objects.append(stop)

def get_stop_by_position(self, pos):
raise NotImplementedError("Should have implemented this")

def get_stops(self):
return self._stop_objects
38 changes: 38 additions & 0 deletions osm2gtfs/core/stops.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# coding=utf-8

import attr


@attr.s
class Stop(object):

osm_id = attr.ib()
osm_type = attr.ib()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need an osm_type? What values can this have?

Copy link
Contributor Author

@pantierra pantierra Nov 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be either node or way. Depending on the type different behaviours might be necessary. E.g for a way you may want to find the center. And we concretely need it for constructing the url to the object here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another reason is also related to #94: osm_id is used for different id spaces, depending on osm_type. Both together can identify an object in OSM, not only osm_id. For the id of the GTFS it is recommended to combine those two in any way.

name = attr.ib()
lat = attr.ib()
lon = attr.ib()
gtfs_id = attr.ib(default=osm_id)
osm_url = attr.ib(default="http://osm.org/" +
str(osm_type) + "/" + str(osm_id))


@attr.s
class StopArea(object):

osm_id = attr.ib()
name = attr.ib()
lat = attr.ib()
lon = attr.ib()

stop_members = attr.ib(default=attr.Factory(list))

def __init__(self, osm_id, stop_members, name=None):
self.osm_id = osm_id
if name is not None:
self.name = name.encode('utf-8')
else:
self.name = name
self.stop_members = stop_members

from osm2gtfs.core.osm_connector import OsmConnector
self.lat, self.lon = OsmConnector.get_center_of_nodes(self.stop_members.values())
9 changes: 5 additions & 4 deletions osm2gtfs/creators/accra/stops_creator_accra.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def create_stop_area(stop_data, schedule):
lat=float(stop_data.lat),
lng=float(stop_data.lon),
name=stop_data.name,
stop_id="SA" + str(stop_data.id)
stop_id="SA" + str(stop_data.osm_id)
)
gtfs_stop_area.location_type = 1
return gtfs_stop_area
Expand All @@ -46,13 +46,13 @@ def create_stop_point(stop_data, schedule):
lat=float(stop_data.lat),
lng=float(stop_data.lon),
name=stop_data.name,
stop_id=str(stop_data.id)
stop_id=str(stop_data.osm_id)
)
return gtfs_stop_point


def get_stop_id(stop):
return stop.id
return stop.osm_id


class StopsCreatorAccra(StopsCreator):
Expand All @@ -61,7 +61,8 @@ def add_stops_to_schedule(self, schedule, data):
stops = data.get_stops()
stops_by_name = {}

for a_stop in stops.values():
for a_stop_id, a_stop in stops.items():
a_stop.osm_id = a_stop_id
if a_stop.name not in stops_by_name:
stops_by_name[a_stop.name] = []
stops_by_name[a_stop.name].append(a_stop)
Expand Down
Loading