/* * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab * * This file is part of PeerfactSim.KOM. * * PeerfactSim.KOM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * PeerfactSim.KOM 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PeerfactSim.KOM. If not, see . * */ package de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.LinkedList; import org.apache.commons.io.IOUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import de.tud.kom.p2psim.impl.topology.movement.modularosm.GPSCalculation; import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor; /** * Generates attraction points out of real data from osm * The maximal number of attraction points can be set * * @author Martin Hellwig * @version 1.0, 02.07.2015 * * Added an upper limit for the number of attraction points. Use 0 to allow all APs in the JSON file. * @author Julian Zobel * @version 1.1, November 2018 * * You now can set an upper limit for the radius. * @author Julian Zobel * @version 1.2, January 2019 * * */ public class JSONAttractionGenerator extends AbstractAttractionProvider { protected int numberOfAttractionPoints; protected String placementJsonFile = ""; protected double maximumRadius = -1; // Values >= 0, or -1 if radius taken from file /** * You have to set a json-file, which has set some POIs * Sample-query for "bar"-POIs in Darmstadt (Bounding Box from [49.4813, 8.5590] to [49.9088, 8,7736]: http://overpass-api.de/api/interpreter?data=%5Bout:json%5D;node%5Bamenity=bar%5D%2849%2E4813%2C8%2E5590%2C49%2E9088%2C8%2E7736%29%3Bout%3B */ @XMLConfigurableConstructor({"numberOfAttractionPoints", "maximumRadius", "placementJsonFile"}) public JSONAttractionGenerator(int numberOfAttractionPoints, double maximumRadius, String placementJsonFile) { this.numberOfAttractionPoints = numberOfAttractionPoints; this.maximumRadius = maximumRadius; this.placementJsonFile = placementJsonFile; createAttractionPoints(); } @Override public LinkedList getAttractionPoints() { if(super.getAttractionPoints().size() == 0) { createAttractionPoints(); } return super.getAttractionPoints(); } protected JSONArray getPOIArray() { assert !placementJsonFile.equals(""); String poiString = ""; JSONArray allPOI = null; FileInputStream inputStream; try { inputStream = new FileInputStream(placementJsonFile); poiString = IOUtils.toString(inputStream); JSONObject poiData = new JSONObject(poiString); allPOI = poiData.getJSONArray("elements"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } return allPOI; } private void createAttractionPoints() { assert super.getAttractionPoints().size() == 0; JSONArray allPOI = getPOIArray(); if(allPOI == null) { throw new UnsupportedOperationException("[JSONAttractionGenerator] POI Data Array cannot be NULL."); } int limit = 0; if(numberOfAttractionPoints == 0 || numberOfAttractionPoints > allPOI.length()) { limit = allPOI.length(); } else { limit = numberOfAttractionPoints; } for(int i = 0; i < limit; i++) { try { String barname = allPOI.getJSONObject(i).getJSONObject("tags").getString("name"); double lat = allPOI.getJSONObject(i).getDouble("lat"); double lon = allPOI.getJSONObject(i).getDouble("lon"); AttractionPoint ap; // check that the point is within the simulation boundaries if(GPSCalculation.isWithinGPSBoundaries(lat, lon)) { // initialize the attraction point with basic information, will be filled now... ap = new AttractionPoint(barname, GPSCalculation.transformGPSWindowToOwnWorld(lat, lon)); // the following setters are allowed to fail // AP weight if(allPOI.getJSONObject(i).getJSONObject("tags").has("weight")) { ap.setWeight(allPOI.getJSONObject(i).getJSONObject("tags").getDouble("weight")); } // AP radius if(allPOI.getJSONObject(i).getJSONObject("tags").has("radius")) { double radius = allPOI.getJSONObject(i).getJSONObject("tags").getDouble("radius"); if(maximumRadius == -1) { ap.setRadius(radius); } else { ap.setRadius(Math.min(maximumRadius, radius)); } } if(allPOI.getJSONObject(i).getJSONObject("tags").has("pauseTimeMin") && allPOI.getJSONObject(i).getJSONObject("tags").has("pauseTimeMax")) { ap.setPauseTime( allPOI.getJSONObject(i).getJSONObject("tags").getLong("pauseTimeMin"), allPOI.getJSONObject(i).getJSONObject("tags").getLong("pauseTimeMax")); } addAttractionPoint(ap); } } catch (JSONException e) { //This bar had no name defined, so there was an error. Not so bad System.out.println(e); } } } }