Advertisement
Guest User

Untitled

a guest
Apr 1st, 2015
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.64 KB | None | 0 0
  1.  
  2.  
  3.  
  4.  
  5.  
  6. package ch.epfl.imhof.osm;
  7.  
  8. import ch.epfl.imhof.Attributed;
  9. import ch.epfl.imhof.Attributes;
  10. import ch.epfl.imhof.Graph;
  11. import ch.epfl.imhof.Map;
  12. import ch.epfl.imhof.geometry.ClosedPolyLine;
  13. import ch.epfl.imhof.geometry.Point;
  14. import ch.epfl.imhof.geometry.PolyLine;
  15. import ch.epfl.imhof.geometry.Polygon;
  16. import ch.epfl.imhof.osm.OSMRelation.Member;
  17. import ch.epfl.imhof.projection.Projection;
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26. import java.util.ArrayList;
  27. import java.util.Arrays;
  28. //import java.util.Collection;
  29. //import java.util.Collections;
  30. import java.util.Comparator;
  31. import java.util.HashMap;
  32. import java.util.HashSet;
  33. import java.util.Iterator;
  34. import java.util.List;
  35. //import java.util.ListIterator;
  36. import java.util.Set;
  37.  
  38. /**
  39. * @author Mario Robert D'Ambrosio (249757)
  40. * @author Nicodème Stalder (234584)
  41. *
  42. */
  43. public final class OSMToGeoTransformer {
  44.  
  45. private final static Set<String> PolyLineKeys = new HashSet<String>(Arrays.asList
  46. ("bridge", "highway", "layer", "man_made", "railway",
  47. "tunnel", "waterway"));
  48.  
  49. private final static Set<String> PolygonKeys = new HashSet<String>(Arrays.asList
  50. ("building", "landuse", "layer", "leisure", "natural",
  51. "waterway"));
  52.  
  53.  
  54. private final Projection projection;
  55. public OSMToGeoTransformer(Projection projection){
  56. this.projection=projection;
  57. }
  58.  
  59. public Map transform(OSMMap map){
  60.  
  61.  
  62.  
  63. final Map.Builder mapToReturn = new Map.Builder();
  64.  
  65.  
  66. putWaysInMap(map,mapToReturn);
  67. map.relations().forEach(e->putRelationsInMap(
  68. assemblePolygon
  69. (e,e.attributes()),
  70. mapToReturn)
  71. );
  72.  
  73.  
  74. return mapToReturn.build();
  75. }
  76.  
  77.  
  78.  
  79. private void putRelationsInMap(List<Attributed<Polygon>> polygons, Map.Builder mapToReturn){
  80. polygons.forEach(e->
  81. mapToReturn.addPolygon(e));
  82. }
  83. private List<ClosedPolyLine> ringsForRole(OSMRelation relation, String role){
  84. List<ClosedPolyLine> ringsToReturn = new ArrayList<>();
  85. Set<OSMWay> ways = waysOfRelation(relation, role);
  86. Graph<OSMNode> graph = graphOfWays(ways);
  87. if(!nodesOfGraphHaveTwoNeighbors(graph))
  88. {
  89. return ringsToReturn;
  90. }
  91. return ringsOfGraph(graph);
  92.  
  93.  
  94. }
  95.  
  96.  
  97.  
  98. private List<ClosedPolyLine> ringsOfGraph(Graph<OSMNode> graph)
  99. {
  100. Set<OSMNode> nodes = new HashSet<OSMNode>(graph.nodes());
  101. Set<OSMNode> nodesRemoved = new HashSet<>();
  102. List<ClosedPolyLine> rings = new ArrayList<>();
  103.  
  104.  
  105. Iterator<OSMNode> i = nodes.iterator();
  106.  
  107. OSMNode firstNode;
  108. List<Point> points;
  109. try{
  110. firstNode = i.next();
  111.  
  112.  
  113. do
  114. {
  115.  
  116.  
  117. points = new ArrayList<>();
  118. points.add(projection.project(firstNode.position()));
  119.  
  120. Set<OSMNode> neighborsOfFirstNode = graph.neighborsOf(firstNode);
  121. Iterator<OSMNode> j = neighborsOfFirstNode.iterator();
  122. OSMNode currentNode = j.next();
  123. points.add(projection.project(currentNode.position()));
  124. nodesRemoved.add(currentNode);
  125.  
  126. Set<OSMNode> neighborsOfSecondNode = graph.neighborsOf(currentNode);
  127. Iterator<OSMNode> k = neighborsOfSecondNode.iterator();
  128. currentNode = k.next();
  129. if(currentNode==firstNode)
  130. {
  131. currentNode=k.next();
  132. }
  133.  
  134.  
  135.  
  136. System.out.println(currentNode.id());
  137.  
  138.  
  139. while(currentNode!=firstNode)
  140. {
  141. points.add(projection.project(currentNode.position()));
  142. nodesRemoved.add(currentNode);
  143. currentNode=neighborOfNodeNotInSet(currentNode,nodesRemoved,graph);
  144. }
  145.  
  146.  
  147. nodesRemoved.add(currentNode);
  148.  
  149.  
  150.  
  151. do
  152. {
  153. if(i.hasNext())
  154. {
  155. firstNode = i.next();
  156. }
  157. }while(i.hasNext() && nodesRemoved.contains(firstNode));
  158. rings.add(new ClosedPolyLine(points));
  159. }while(i.hasNext());
  160.  
  161. }catch(Exception e){}
  162.  
  163.  
  164. return rings;
  165.  
  166.  
  167. }
  168.  
  169.  
  170. private OSMNode neighborOfNodeNotInSet(OSMNode node, Set<OSMNode> nodes, Graph<OSMNode> graph)
  171. {
  172.  
  173.  
  174. Set<OSMNode> neighbors = graph.neighborsOf(node);
  175.  
  176. Iterator<OSMNode> i = neighbors.iterator();
  177.  
  178. OSMNode nodeTMP = i.next();
  179.  
  180.  
  181. if(!nodes.contains(nodeTMP))
  182. {
  183. return nodeTMP;
  184. }
  185.  
  186. return i.next();
  187.  
  188. }
  189.  
  190.  
  191. private Set<OSMWay> waysOfRelation(OSMRelation relation, String role)
  192. {
  193. final List<Member> members = relation.members();
  194.  
  195. final Set<OSMWay> ways = new HashSet<>();
  196.  
  197. for(Member memberTMP : members)
  198. {
  199.  
  200. /*System.out.println("***debut de waysOfRelation");
  201. System.out.println(memberTMP.type()==OSMRelation.Member.Type.WAY);
  202. System.out.println(memberTMP.role());
  203. System.out.println(role);
  204. System.out.println(role==memberTMP.role());
  205. System.out.println("***fin de waysOfRelation");*/
  206.  
  207.  
  208.  
  209. if (memberTMP.type()==OSMRelation.Member.Type.WAY && memberTMP.role().equals(role))
  210. {
  211. //System.out.println("yes");
  212. ways.add((OSMWay)memberTMP.member());
  213. }
  214. }
  215.  
  216. return ways;
  217. }
  218.  
  219. private boolean nodesOfGraphHaveTwoNeighbors(Graph<OSMNode> graph)
  220. {
  221. Set<OSMNode> nodes = graph.nodes();
  222.  
  223. for(OSMNode nodeTMP : nodes)
  224. {
  225. if(graph.neighborsOf(nodeTMP).size()!=2)
  226. {
  227. Set<OSMNode> s = graph.neighborsOf(nodeTMP);
  228. Iterator<OSMNode> i = s.iterator();
  229. System.out.println(i.next().id());
  230. System.out.println(i.hasNext());
  231.  
  232.  
  233. return false;
  234. }
  235. }
  236.  
  237. return true;
  238.  
  239. }
  240.  
  241.  
  242. private Graph<OSMNode> graphOfWays(Set<OSMWay> ways)
  243. {
  244. Graph.Builder<OSMNode> graphToReturn = new Graph.Builder<OSMNode>();
  245. List <OSMNode> nodes;
  246.  
  247. for(OSMWay way: ways)
  248. {
  249. //final List <OSMNode> nodes = way.nodes();
  250.  
  251. nodes = way.nodes();
  252.  
  253.  
  254. Iterator<OSMNode> i = nodes.iterator();
  255. OSMNode nodeTMP1 = i.next();
  256. OSMNode nodeTMP2;
  257. graphToReturn.addNode(nodeTMP1);
  258. while(i.hasNext())
  259. {
  260. nodeTMP2=i.next();
  261. graphToReturn.addNode(nodeTMP2);
  262. graphToReturn.addEdge(nodeTMP1, nodeTMP2);
  263. nodeTMP1 = nodeTMP2;
  264. }
  265.  
  266. }
  267.  
  268.  
  269. return graphToReturn.build();
  270.  
  271.  
  272.  
  273.  
  274.  
  275. }
  276.  
  277. private List<Attributed<Polygon>> assemblePolygon(OSMRelation relation, Attributes attributes){
  278. return PolygonToAttributed(
  279. createPolygons(
  280. PolyLineSort(
  281. ringsForRole(relation, "outer")),
  282. PolyLineSort(
  283. ringsForRole(relation,"inner"))
  284. ),
  285. Attributesfilter
  286. (attributes, Type.Polygon)
  287. );
  288. }
  289.  
  290. private List<Polygon> createPolygons(List<ClosedPolyLine> outers,List<ClosedPolyLine> inners ){
  291. final List<Polygon> polygons= new ArrayList<Polygon>();
  292. for (int i=0, n=outers.size(); i<n; i++)
  293. { final ClosedPolyLine e= outers.get(i);
  294. final List<ClosedPolyLine> innersOfe= new ArrayList<ClosedPolyLine>();
  295. innersOfe.addAll(innersOf(e,inners));
  296. inners.removeAll(innersOfe);
  297. polygons.add(new Polygon(e, innersOfe));
  298. }
  299. return polygons;
  300. }
  301.  
  302. private Set<ClosedPolyLine> innersOf(ClosedPolyLine outer, List<ClosedPolyLine> inners ){
  303. final Set<ClosedPolyLine> innersOf= new HashSet<ClosedPolyLine>();
  304. inners.forEach(e->{
  305. if(contains(outer,e))
  306. {innersOf.add(e);
  307. }
  308. }
  309.  
  310. );
  311. return innersOf;
  312. }
  313.  
  314. private boolean contains(ClosedPolyLine outer, ClosedPolyLine inner){
  315. //inner.points().forEach(point->{if(!outer.containsPoint(point)){return false;}});
  316. for(Point p: inner.points()){
  317. if(!outer.containsPoint(p)){
  318. return false;
  319. }
  320. }
  321. return true;
  322. }
  323.  
  324.  
  325. private List<Attributed<Polygon>> PolygonToAttributed(List<Polygon> polygons, Attributes attributes) {
  326.  
  327. final List<Attributed<Polygon>> attributedPolygons = new ArrayList<Attributed<Polygon>>();
  328.  
  329. if(!attributes.isEmpty()){
  330. polygons.forEach(e->
  331. attributedPolygons.add
  332. (new Attributed<Polygon>(e,
  333. attributes)));
  334. }
  335. return attributedPolygons;
  336.  
  337.  
  338. }
  339.  
  340. private static enum Type{
  341. PolyLine("polyline"), Polygon("polygon");
  342. private Type(String type){}
  343. }
  344.  
  345. private Attributes Attributesfilter(Attributes attributes, Type type){
  346.  
  347. switch(type) {
  348. case PolyLine :
  349. return (attributes.keepOnlyKeys(PolyLineKeys));
  350. case Polygon :
  351. return attributes.keepOnlyKeys(PolygonKeys);
  352. default: return new Attributes(new HashMap<String,String>());
  353. }
  354.  
  355. }
  356.  
  357. private List<ClosedPolyLine> PolyLineSort(List<ClosedPolyLine> polylines){
  358. polylines.sort(new Comparator<ClosedPolyLine>(){
  359. public int compare(ClosedPolyLine p1, ClosedPolyLine p2){
  360. if(p1.area()<p2.area()){return -1;}
  361. else if(p1.area()>p2.area()){return 1;}
  362. return 0;
  363. };
  364. }
  365. );
  366. return polylines;
  367. }
  368.  
  369.  
  370.  
  371. private boolean isAeraWay(OSMWay way)
  372. {
  373.  
  374. if(way.isClosed()) {
  375. try{
  376. if(way.attributes().get("area").equals("yes")
  377. ||way.attributes().get("area").equals("1")
  378. ||way.attributes().get("area").equals("true")){return true;}
  379. }catch(NullPointerException e){}
  380.  
  381. final String[] keys = {"aeroway", "amenity", "building", "harbour", "historic",
  382. "landuse", "leisure", "man_made", "military", "natural",
  383. "office", "place", "power", "public_transport", "shop",
  384. "sport", "tourism", "water", "waterway", "wetland"};
  385. for(int i=0; i<keys.length; i++)
  386. {
  387. if (way.attributes().contains(keys[i]))
  388. {
  389. return true;
  390. }
  391. }
  392. }
  393.  
  394. return false;
  395.  
  396. }
  397.  
  398.  
  399.  
  400. private void putWaysInMap(OSMMap map, Map.Builder mapToReturn)
  401. {
  402. final List<OSMWay> ways = map.ways();
  403.  
  404.  
  405. for(OSMWay wayTMP : ways)
  406. {
  407.  
  408. if(isAeraWay(wayTMP))
  409. {
  410. try{
  411. mapToReturn.addPolygon(wayToAttributedPolygon(wayTMP));
  412. }catch (Exception e){}
  413. }
  414. else
  415. {
  416. try{
  417. mapToReturn.addPolyLine(wayToAttributedPolyLine(wayTMP));
  418. }catch (Exception e){}
  419.  
  420. }
  421. }
  422.  
  423. }
  424.  
  425.  
  426.  
  427.  
  428. private Attributed<Polygon> wayToAttributedPolygon(OSMWay way) throws Exception
  429. {
  430. final Polygon polygon = new Polygon((ClosedPolyLine)wayToPolyline(way));
  431. final Attributes attributes = Attributesfilter(way.attributes(), Type.Polygon);
  432. if(attributes.isEmpty()) throw new Exception();
  433. return new Attributed<Polygon>(polygon,attributes);
  434. }
  435.  
  436.  
  437. private Attributed<PolyLine> wayToAttributedPolyLine(OSMWay way) throws Exception
  438. {
  439.  
  440. final PolyLine polyline = wayToPolyline(way);
  441. final Attributes attributes = Attributesfilter(way.attributes(), Type.PolyLine);
  442.  
  443. if(attributes.isEmpty()) throw new Exception();
  444. return new Attributed<PolyLine>(polyline,attributes);
  445. }
  446.  
  447.  
  448. private PolyLine wayToPolyline(OSMWay way)
  449. {
  450. final List<OSMNode> nodes = way.nodes();
  451. final PolyLine.Builder polyLine = new PolyLine.Builder();
  452.  
  453. if (way.isClosed())
  454. {
  455. for (int i=0, n=nodes.size(); i < n; i++){
  456. if(i!=n-1){
  457. polyLine.addPoint(projection.project(nodes.get(i).position()));
  458. }
  459. }
  460. return polyLine.buildClosed();
  461. }
  462. else
  463. {
  464. for(OSMNode nodeTMP : nodes)
  465. {
  466. polyLine.addPoint(projection.project(nodeTMP.position()));
  467. }
  468. return polyLine.buildOpen();
  469. }
  470.  
  471. }
  472.  
  473.  
  474.  
  475.  
  476. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement