GreenIndexGraphStorageBuilder.java
- /* This file is part of Openrouteservice.
- *
- * Openrouteservice is free software; you can redistribute it and/or modify it under the terms of the
- * GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License along with this library;
- * if not, see <https://www.gnu.org/licenses/>.
- */
- package org.heigit.ors.routing.graphhopper.extensions.storages.builders;
- import com.graphhopper.GraphHopper;
- import com.graphhopper.reader.ReaderWay;
- import com.graphhopper.storage.GraphExtension;
- import com.graphhopper.util.EdgeIteratorState;
- import com.graphhopper.util.Helper;
- import org.apache.log4j.Logger;
- import org.heigit.ors.routing.graphhopper.extensions.storages.GreenIndexGraphStorage;
- import java.io.BufferedReader;
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * Created by lliu on 13/03/2017.
- */
- public class GreenIndexGraphStorageBuilder extends AbstractGraphStorageBuilder {
- private static final Logger LOGGER = Logger.getLogger(GreenIndexGraphStorageBuilder.class.getName());
- private GreenIndexGraphStorage storage;
- private final Map<Long, Double> greenIndices = new HashMap<>();
- private static final int TOTAL_LEVEL = 64;
- private static final int DEFAULT_LEVEL = TOTAL_LEVEL - 1;
- private final Map<Byte, SlotRange> slots = new HashMap<>(TOTAL_LEVEL);
- @Override
- public GraphExtension init(GraphHopper graphhopper) throws Exception {
- if (storage != null)
- throw new Exception("GraphStorageBuilder has been already initialized.");
- // TODO Refactoring Check if the _greenIndexFile exists
- String csvFile = parameters.get("filepath");
- readGreenIndicesFromCSV(csvFile);
- prepareGreenIndexSlots();
- storage = new GreenIndexGraphStorage();
- return storage;
- }
- private void prepareGreenIndexSlots() {
- double max = Collections.max(greenIndices.values());
- double min = Collections.min(greenIndices.values());
- double step = (max - min) / TOTAL_LEVEL;
- // Divide the range of raw green index values into TOTAL_LEVEL,
- // then map the raw value to [0..TOTAL_LEVEL - 1]
- for (byte i = 0; i < TOTAL_LEVEL; i++) {
- slots.put(i, new SlotRange(min + i * step, min + (i + 1) * step));
- }
- }
- private void readGreenIndicesFromCSV(String csvFile) throws IOException {
- try (BufferedReader csvBuffer = new BufferedReader(new FileReader(csvFile))) {
- String row;
- // Jump the header line
- row = csvBuffer.readLine();
- char separator = row.contains(";") ? ';' : ',';
- String[] rowValues = new String[2];
- while ((row = csvBuffer.readLine()) != null) {
- if (!parseCSVrow(row, separator, rowValues))
- continue;
- greenIndices.put(Long.parseLong(rowValues[0]), Double.parseDouble(rowValues[1]));
- }
- } catch (IOException openFileEx) {
- LOGGER.error(openFileEx.getStackTrace());
- throw openFileEx;
- }
- }
- private boolean parseCSVrow(String row, char separator, String[] rowValues) {
- if (Helper.isEmpty(row))
- return false;
- int pos = row.indexOf(separator);
- if (pos > 0) {
- rowValues[0] = row.substring(0, pos).trim();
- rowValues[1] = row.substring(pos + 1).trim();
- // read, check and push "osm_id" and "ungreen_factor" values
- return !Helper.isEmpty(rowValues[0]) && !Helper.isEmpty(rowValues[1]);
- }
- return false;
- }
- @Override
- public void processWay(ReaderWay way) {
- // do nothing
- }
- @Override
- public void processEdge(ReaderWay way, EdgeIteratorState edge) {
- storage.setEdgeValue(edge.getEdge(), calcGreenIndex(way.getId()));
- }
- private static class SlotRange {
- double left = 0.0;
- double right = 0.0;
- SlotRange(double l, double r) {
- this.left = l;
- this.right = r;
- }
- boolean within(double val) {
- // check if the @val falls in [left, right] range
- return (val >= left) && (val <= right);
- }
- }
- private byte calcGreenIndex(long id) {
- Double gi = greenIndices.get(id);
- // No such @id key in the _greenIndices, or the value of it is null
- // We set its green level to TOTAL_LEVEL/2 indicating the middle value for such cases
- // TODO Refactoring this DEFAULT_LEVEL should be put in the ors-config.json file and
- // injected back in the code
- if (gi == null)
- return (byte) (DEFAULT_LEVEL);
- for (Map.Entry<Byte, SlotRange> s : slots.entrySet()) {
- if (s.getValue().within(gi))
- return s.getKey();
- }
- return (byte) (DEFAULT_LEVEL);
- }
- @Override
- public String getName() {
- return "GreenIndex";
- }
- }