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;
+    }
+}