diff --git a/src/main/java/si/ijs/urbanite/simserver/travel_demand/Districts.java b/src/main/java/si/ijs/urbanite/simserver/travel_demand/Districts.java new file mode 100644 index 0000000000000000000000000000000000000000..24cacafde97c077483f4e322a72d0d824d24af2f --- /dev/null +++ b/src/main/java/si/ijs/urbanite/simserver/travel_demand/Districts.java @@ -0,0 +1,91 @@ +package si.ijs.urbanite.simserver.travel_demand; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.checkerframework.checker.units.qual.A; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.matsim.core.utils.collections.ArrayMap; + + +public class Districts { + //TODO add shape files to drive + public static ArrayList<String> getBilbaoDistricts() { +// DEUSTO = ['D1 NORTE','D1 SUR'] +// URIBARRI = ["CASTANOS","D2 ALTO","RIA ESTE","RIA OESTE","MB L3 (METRO BILBAO LINEA 3)"] +// OTXARKOAGA_TXURDINAGA = ["OTXARKOAGA","TXURDINAGA"] +// BEGONA = ["D4 SUR"] +// IBAIONDO = ["CASCO VIEJO","D5 ESTE","D5 OESTE"] +// ABANDO = ['CENTRO','HOSPITAL','ACCESOS V (ACCESOS VIARIOS)','INTERMODAL'] +// ERREKALDE = ["D7 NORTE","D7 SUR"] +// BASURT_ZORROTZA = ["BASURTO","ZORROZA"] + + + ArrayMap<String, ArrayList> districts = new ArrayMap<>(); + districts.put("Deusto", new ArrayList<>(Arrays.asList("Deusto", "D1 NORTE", "D1 SUR"))); + districts.put("Uribarri", new ArrayList<>(Arrays.asList("Uríbarri", "D2 ALTO", "RIA OESTE", "MB_L3"))); + districts.put("Otxarkoaga-Txurdinaga", new ArrayList<>(Arrays.asList("OTXARKOAGA", "TXURDINAGA"))); + districts.put("Begoña", new ArrayList<>(Arrays.asList("D4 SUR"))); + districts.put("Ibaiondo", new ArrayList<>(Arrays.asList("CASCO_VIEJO", "D5 OESTE"))); + districts.put("Abando", new ArrayList<>(Arrays.asList("CENTRO", "HOSPITAL", "ACCESOS_VIARIOS", "INTERMODAL"))); + districts.put("Recalde", new ArrayList<>(Arrays.asList("D7 NORTE", "D7 SUR"))); + districts.put("Basurto-Zorroza", new ArrayList<>(Arrays.asList("BASURTO", "ZORROZA"))); + + + ArrayList<String> districtsMain = new ArrayList<>(Arrays.asList("Deusto", "Uribarri", "Otxarkoaga-Txurdinaga", "Begoña", "Ibaiondo", "Abando", "Recalde", "Basurto-Zorroza")); + + + return districtsMain; + + } + + public static ArrayMap<String,Polygon> readShapeFile() throws IOException, ParseException { + + + ArrayList<String> districts = getBilbaoDistricts(); + ArrayMap<String, Polygon> district_polygon = new ArrayMap<>(); + + String path = Paths.get("data", "bilbao", "before_simulation", "shapes.json").toString(); + + JSONParser parser = new JSONParser(); + FileReader reader = new FileReader(path); + Object obj = parser.parse(reader); + JSONArray a = (JSONArray) obj; + + + for (Object district : a) { + JSONObject dist = (JSONObject) district; + String name = (String) dist.get("description"); + if (districts.contains(name)) { + List<Point> vertices = new ArrayList<>(); + JSONObject n = (JSONObject) dist.get("location"); + JSONArray coord = (JSONArray) n.get("coordinates"); + for (int i=0;i<coord.size();i++){ + ArrayList c = (ArrayList) coord.get(i); + vertices.add(new Point((Double) c.get(0),(Double)c.get(1))); + } + Polygon polygon = new Polygon(vertices); + district_polygon.put(name,polygon); + } + } + return district_polygon; + } + + public static void readFacilityFile(){ + + String path = Paths.get("data","bilbao","before_simulation","other.geojson").toString(); + + } + + public static void main(String[] args) throws IOException, ParseException { + + } +} diff --git a/src/main/java/si/ijs/urbanite/simserver/travel_demand/Facilities.java b/src/main/java/si/ijs/urbanite/simserver/travel_demand/Facilities.java new file mode 100644 index 0000000000000000000000000000000000000000..4da56881f338a13c1fec152c020cefe98fde1bf2 --- /dev/null +++ b/src/main/java/si/ijs/urbanite/simserver/travel_demand/Facilities.java @@ -0,0 +1,129 @@ +package si.ijs.urbanite.simserver.travel_demand; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import org.matsim.api.core.v01.Coord; +import org.matsim.core.utils.geometry.CoordinateTransformation; +import org.matsim.core.utils.geometry.transformations.TransformationFactory; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicLong; + +public class Facilities { + private static final AtomicLong idGenerator = new AtomicLong(0); + + public static long getNextId() { + return idGenerator.incrementAndGet(); + } + + public static void createFacilityFromPoint(FileWriter fileWriter, String path, String type) throws IOException { + + + File file = new File(path); + CoordinateTransformation transformation = TransformationFactory.getCoordinateTransformation( + TransformationFactory.WGS84,"EPSG:32630"); + ObjectMapper mapper = new ObjectMapper(); + JsonNode rootNode = mapper.readTree(file); + + // Get the features array from the GeoJSON + ArrayNode features = (ArrayNode) rootNode.get("features"); + + // Iterate over each feature in the array + for (JsonNode feature : features) { + // Get the geometry of the feature + JsonNode geometry = feature.get("geometry"); + + // Get the coordinates of the geometry + JsonNode coordinates = geometry.get("coordinates"); + String typePolygonPoint = geometry.get("type").asText(); + + if (typePolygonPoint.matches("Polygon")){ + double x=0.0; + double y=0.0; + int counter=0; + //iterate over coordinate, average them + if (coordinates.isArray()){ + for (JsonNode node:coordinates){ + if (node.isArray()){ + for (JsonNode node1:node){ + x+=node1.get(0).asDouble(); + y+=node1.get(1).asDouble(); + counter++; + } + } + } + } + x=x/counter; + y=y/counter; + + Coord coord = transformation.transform(new Coord(x,y)); + long id = getNextId(); + String facility = "<facility id=\""+id+"\" x=\""+ coord.getX()+"\" y=\""+coord.getY()+"\">\n"; + String activity2 = "<activity type=\""+type+"\"/>\n"; + String facilityClose = "</facility>\n"; + fileWriter.append(facility+activity2+facilityClose); + + } + + else if (typePolygonPoint.matches("Point")){ + double x = coordinates.get(0).asDouble(); + double y = coordinates.get(1).asDouble(); + Coord coord = transformation.transform(new Coord(x,y)); + long id = getNextId(); + String facility = "<facility id=\""+id+"\" x=\""+ coord.getX()+"\" y=\""+coord.getY()+"\">\n"; + String activity1 = "<activity type=\"work\"/>\n"; + String activity2 = "<activity type=\""+type+"\"/>\n"; + String facilityClose = "</facility>\n"; + fileWriter.append(facility+activity1+activity2+facilityClose); + + } + + + + } + } + + public static void createFacilityFromPolygon() { + + + } + + //TODO add home, education, work, other, leisure to onedrive + public static void createFacility(String city) throws IOException { + String homePath = Paths.get("data", city, "before_simulation", "home.geojson").toString(); + String educationPath = Paths.get("data", city, "before_simulation", "education.geojson").toString(); + String leisurePath = Paths.get("data", city, "before_simulation", "leisure.geojson").toString(); + String otherPath = Paths.get("data", city, "before_simulation", "other.geojson").toString(); + + String facilitiesPath = Paths.get("data", city, "original_input", "facilities.xml").toString(); + + + FileWriter fw = new FileWriter(facilitiesPath); + String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<!DOCTYPE facilities SYSTEM \"http://www.matsim.org/files/dtd/facilities_v2.dtd\">\n" + + "<facilities>"; + fw.write(header); + + createFacilityFromPoint(fw,educationPath,"education"); + createFacilityFromPoint(fw,leisurePath,"leisure"); + createFacilityFromPoint(fw,otherPath,"other"); + createFacilityFromPoint(fw,homePath,"home"); + + + fw.append("</facilities>"); + fw.close(); + + + + } + + public static void main(String[] args) throws IOException { + createFacility("bilbao"); + + } +} diff --git a/src/main/java/si/ijs/urbanite/simserver/travel_demand/Point.java b/src/main/java/si/ijs/urbanite/simserver/travel_demand/Point.java new file mode 100644 index 0000000000000000000000000000000000000000..d53ab5f54a354e002965dce371f482a03d4fbd46 --- /dev/null +++ b/src/main/java/si/ijs/urbanite/simserver/travel_demand/Point.java @@ -0,0 +1,11 @@ +package si.ijs.urbanite.simserver.travel_demand; + +public class Point { + public final double x; + public final double y; + + public Point(double x, double y) { + this.x = x; + this.y = y; + } +} diff --git a/src/main/java/si/ijs/urbanite/simserver/travel_demand/Polygon.java b/src/main/java/si/ijs/urbanite/simserver/travel_demand/Polygon.java new file mode 100644 index 0000000000000000000000000000000000000000..8a547a3c109beb1fac1650133d97578826ab600b --- /dev/null +++ b/src/main/java/si/ijs/urbanite/simserver/travel_demand/Polygon.java @@ -0,0 +1,34 @@ +package si.ijs.urbanite.simserver.travel_demand; + + +import java.util.List; + +public class Polygon { + private final List<Point> vertices; + + public Polygon(List<Point> vertices) { + this.vertices = vertices; + } + + public boolean contains(Point point) { + int crossings = 0; + + for (int i = 0; i < vertices.size(); i++) { + Point vertex1 = vertices.get(i); + Point vertex2 = vertices.get((i + 1) % vertices.size()); + + if (vertex1.y <= point.y && vertex2.y > point.y || + vertex2.y <= point.y && vertex1.y > point.y) { + double dx = vertex2.x - vertex1.x; + double dy = vertex2.y - vertex1.y; + double x = vertex1.x + (point.y - vertex1.y) / dy * dx; + + if (x < point.x) { + crossings++; + } + } + } + + return crossings % 2 != 0; + } +}