示例#1
0
def create_contours_for_station(departure_station,
                                stations,
                                config,
                                overwrite_existing=False,
                                use_saved_data=False):
    logger.info(departure_station)
    max_level = 180
    filepaths = []
    contourmap = nsmaps.contourmap.Contour(departure_station, stations, config)

    filepath_geojson = os.path.join(
        DATA_DIR, 'contours/' + departure_station.get_code() + '.geojson')
    if not overwrite_existing and os.path.exists(filepath_geojson):
        print('WARNING: skipping station ' + departure_station.get_code() +
              ', files already exist.')
        return
    filepaths.append(filepath_geojson)
    if use_saved_data:
        contourmap.load()
    else:
        contourmap.create_contour_data()
        contourmap.save()
    levels_minor = numpy.linspace(0, max_level, num=37)
    contourmap.create_geojson(filepath_geojson,
                              stroke_width=4,
                              levels=levels_minor,
                              overwrite=overwrite_existing)
示例#2
0
 def recreate_missing_destinations(self,
                                   departure_timestamp,
                                   dry_run=False):
     ignore_station_ids = [
         'HRY', 'WTM', 'KRW', 'VMW', 'RTST', 'WIJ', 'SPV', 'SPH'
     ]
     for station in self.stations:
         if not station.has_travel_time_data():
             continue
         stations_missing = self.get_missing_destinations(
             station.get_travel_time_filepath())
         stations_missing_filtered = []
         for station_missing in stations_missing:
             if station_missing.get_code() not in ignore_station_ids:
                 stations_missing_filtered.append(stations_missing)
                 logger.info(station.get_name() + ' has missing station: ' +
                             station_missing.get_name())
         if stations_missing_filtered and not dry_run:
             json_data = self.create_trip_data_from_station(
                 station, departure_timestamp)
             with open(station.get_travel_time_filepath(), 'w') as fileout:
                 fileout.write(json_data)
         else:
             logger.info('No missing destinations for ' +
                         station.get_name() + ' with ' +
                         str(len(ignore_station_ids)) + ' ignored.')
示例#3
0
    def create_trip_data_from_station(self, station_from, timestamp):
        """ timestamp format: DD-MM-YYYY hh:mm """
        via = ""
        data = {'stations': []}
        data['stations'].append({
            'name': station_from.get_name(),
            'id': station_from.get_code(),
            'travel_time_min': 0,
            'travel_time_planned': "0:00"
        })
        nsapi = ns_api.NSAPI(USERNAME, APIKEY)
        for station in self.stations:
            if station.get_code() == station_from.get_code():
                continue
            trips = []
            try:
                trips = nsapi.get_trips(timestamp, station_from.get_code(),
                                        via, station.get_code())
            except TypeError as error:
                # this is a bug in ns-api, should return empty trips in case there are no results
                logger.error(
                    'Error while trying to get trips for destination: ' +
                    station.get_name() + ', from: ' + station_from.get_name())
                continue
            except requests.exceptions.HTTPError as error:
                # 500: Internal Server Error does always happen for some stations (example are Eijs-Wittem and Kerkrade-West)
                logger.error(
                    'HTTP Error while trying to get trips for destination: ' +
                    station.get_name() + ', from: ' + station_from.get_name())
                continue

            if not trips:
                continue

            shortest_trip = trips[0]
            for trip in trips:
                travel_time = datetime.strptime(trip.travel_time_planned,
                                                "%H:%M").time()
                trip.travel_time_min = travel_time.hour * 60 + travel_time.minute
                if trip.travel_time_min < shortest_trip.travel_time_min:
                    shortest_trip = trip

            logger.info(shortest_trip.departure + ' - ' +
                        shortest_trip.destination)
            data['stations'].append({
                'name':
                shortest_trip.destination,
                'id':
                self.get_station_code(shortest_trip.destination),
                'travel_time_min':
                shortest_trip.travel_time_min,
                'travel_time_planned':
                shortest_trip.travel_time_planned
            })
            # time.sleep(0.3)  # balance load on the NS server
        json_data = json.dumps(data,
                               indent=4,
                               sort_keys=True,
                               ensure_ascii=False)
        return json_data
示例#4
0
    def interpolate_travel_time(q, position, stations, kdtree, gps, latrange,
                                lonrange, altitude, n_nearest,
                                cycle_speed_kmh):
        # n_nearest: check N nearest stations as best start for cycle route
        logger.info('interpolate_travel_time')
        Z = numpy.zeros((int(latrange.shape[0]), int(lonrange.shape[0])))
        min_per_m = 1.0 / (cycle_speed_kmh / 60.0 * 1000.0)
        for i, lat in enumerate(latrange):
            if i % (len(latrange) / 10) == 0:
                logger.debug(str(int(i / len(latrange) * 100)) + '%')

            for j, lon in enumerate(lonrange):
                x, y, z = gps.lla2ecef([lat, lon, altitude])
                distances, indexes = kdtree.query([x, y, z], n_nearest)
                min_travel_time = sys.float_info.max
                for distance, index in zip(distances, indexes):
                    if stations[index].travel_time_min is None:
                        continue
                    travel_time = stations[
                        index].travel_time_min + distance * min_per_m
                    if travel_time < min_travel_time:
                        min_travel_time = travel_time
                Z[i][j] = min_travel_time
        data = ContourData()
        data.index_begin = position
        data.Z = Z
        q.put(data)
        logger.info('end interpolate_travel_time')
        return
示例#5
0
    def create_geojson(self,
                       filepath,
                       stroke_width=1,
                       levels=[],
                       norm=None,
                       overwrite=False):
        if not overwrite and os.path.exists(filepath):
            logger.error('Output file ' + filepath +
                         ' already exists. Will not override.')
            return

        figure = Figure(frameon=False)
        FigureCanvas(figure)
        ax = figure.add_subplot(111)
        # contours = plt.contourf(lonrange, latrange, Z, levels=levels, cmap=plt.cm.plasma)
        contours = ax.contour(self.lonrange,
                              self.latrange,
                              self.Z,
                              levels=levels,
                              norm=norm,
                              cmap=plt.cm.jet,
                              linewidths=3)

        ndigits = len(str(int(1.0 / self.config.stepsize_deg))) + 1
        logger.info('converting contour to geojson file: ' + filepath)
        geojsoncontour.contour_to_geojson(
            contour=contours,
            geojson_filepath=filepath,
            contour_levels=levels,
            min_angle_deg=self.config.min_angle_between_segments,
            ndigits=ndigits,
            unit='min',
            stroke_width=stroke_width)

        cbar = figure.colorbar(contours, format='%d', orientation='horizontal')
        cbar.set_label('Travel time [minutes]')
        # cbar.set_ticks(self.config.colorbar_ticks)
        ax.set_visible(False)
        figure.savefig(
            filepath.replace('.geojson', '') + "_colorbar.png",
            dpi=90,
            bbox_inches='tight',
            pad_inches=0,
            transparent=True,
        )
示例#6
0
    def create_contour_data(self):
        logger.info('BEGIN')
        if self.departure_station.has_travel_time_data():
            self.stations.travel_times_from_json(
                self.departure_station.get_travel_time_filepath())
        else:
            logger.error('Input file ' +
                         self.departure_station.get_travel_time_filepath() +
                         ' not found. Skipping station.')

        start = timer()
        numpy.set_printoptions(3, threshold=100, suppress=True)  # .3f

        altitude = 0.0
        self.Z = numpy.zeros(
            (int(self.lonrange.shape[0]), int(self.latrange.shape[0])))
        gps = nsmaps.utilgeo.GPS()

        positions = []
        for station in self.stations:
            x, y, z = gps.lla2ecef(
                [station.get_lat(),
                 station.get_lon(), altitude])
            positions.append([x, y, z])

        logger.info('starting spatial interpolation')

        # tree to find nearest neighbors
        tree = KDTree(positions)

        queue = Queue()
        processes = []
        if self.config.n_nearest > len(self.stations):
            self.config.n_nearest = len(self.stations)
        latrange_per_process = int(
            len(self.latrange) / self.config.n_processes)
        for i in range(0, self.config.n_processes):
            begin = i * latrange_per_process
            end = (i + 1) * latrange_per_process
            latrange_part = self.latrange[begin:end]
            process = Process(target=self.interpolate_travel_time,
                              args=(queue, i, self.stations.stations, tree,
                                    gps, latrange_part, self.lonrange,
                                    altitude, self.config.n_nearest,
                                    self.config.cycle_speed_kmh))
            processes.append(process)

        for process in processes:
            process.start()

        # get from the queue and append the values
        for i in range(0, self.config.n_processes):
            data = queue.get()
            index_begin = data.index_begin
            begin = int(index_begin * len(self.latrange) /
                        self.config.n_processes)
            end = int((index_begin + 1) * len(self.latrange) /
                      self.config.n_processes)
            self.Z[0:][begin:end] = data.Z

        for process in processes:
            process.join()

        end = timer()
        logger.info('finished spatial interpolation in ' + str(end - start) +
                    ' [sec]')
        logger.info('END')