Rev 344 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (c) 2014.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program 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.
*/
package uk.me.parabola.splitter;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.awt.geom.Path2D;
import java.awt.geom.Area;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* Class to read a polygon description file.
* Expected input are nodes and ways. Ways with
* tag name=* and mapid=nnnnnnnn should describe polygons
* which are used to calculate area lists.
* @author GerdP
*
*/
class PolygonDescProcessor
extends AbstractMapProcessor
{
private Long2ObjectOpenHashMap
<Node> nodes =
new Long2ObjectOpenHashMap
<>();
private final List<PolygonDesc
> polygonDescriptions =
new ArrayList<>();
final int resolution
;
public PolygonDescProcessor
(int resolution
) {
this.
resolution = resolution
;
}
@
Override
public void processNode
(Node n
){
// round all coordinates to be on the used grid.
int lat = getRoundedCoord
(n.
getMapLat());
int lon = getRoundedCoord
(n.
getMapLon());
double roundedLat = Utils.
toDegrees(lat
);
double roundedLon = Utils.
toDegrees(lon
);
Node rNode =
new Node();
rNode.
set(n.
getId(),roundedLat,roundedLon
);
nodes.
put(rNode.
getId(), rNode
);
}
@
Override
public void processWay
(Way w
){
String name = w.
getTag("name");
if (name ==
null){
System.
out.
println("name missing, ignoring way " + w.
getId());
return;
}
String mapIdString = w.
getTag("mapid");
if (mapIdString ==
null){
System.
out.
println("mapid missing, ignoring way " + w.
getId());
return;
}
int mapId
;
try{
mapId =
Integer.
parseInt(mapIdString
);
} catch (NumberFormatException e
){
System.
out.
println("invalid mapid in way " + w.
getId());
return;
}
Path2D path =
null;
for (long ref : w.
getRefs()){
Node n = nodes.
get(ref
);
if (n
!=
null){
if (path ==
null){
path =
new Path2D.
Double();
path.
moveTo(n.
getMapLon(), n.
getMapLat());
} else
path.
lineTo(n.
getMapLon(), n.
getMapLat());
}
}
PolygonDesc pd =
new PolygonDesc
(name,
new Area(path
), mapId
);
polygonDescriptions.
add(pd
);
}
@
Override
public boolean endMap
(){
nodes =
null;
System.
out.
println("found " + polygonDescriptions.
size() +
" named polygons");
return true;
}
/**
* @return the combined polygon
*/
Area getCombinedPolygon
(){
Area combinedArea =
new Area();
for (PolygonDesc pd : polygonDescriptions
){
combinedArea.
add(pd.
area);
}
return combinedArea
;
}
/**
* Calculate and write the area lists for each named polygon.
* @param fileOutputDir
* @param areas the list of all areas
* @param kmlOutputFile optional kml file name or null
* @param outputType file name extension of output files
* @throws IOException
*/
public void writeListFiles
(File fileOutputDir,
List<uk.
me.
parabola.
splitter.
Area> areas,
String kmlOutputFile,
String outputType
) throws IOException {
for (PolygonDesc pd : polygonDescriptions
){
List<uk.
me.
parabola.
splitter.
Area> areasPart =
new ArrayList<>();
for (uk.
me.
parabola.
splitter.
Area a : areas
){
if (pd.
area.
intersects(a.
getRect()))
areasPart.
add(a
);
}
AreaList al =
new AreaList
(areasPart
);
if (kmlOutputFile
!=
null){
File out =
new File(kmlOutputFile
);
String kmlOutputFilePart = pd.
name +
"-" + out.
getName();
if (out.
getParent() !=
null)
out =
new File(out.
getParent(), kmlOutputFilePart
);
else
out =
new File(kmlOutputFilePart
);
if (out.
getParent() ==
null)
out =
new File(fileOutputDir, kmlOutputFilePart
);
System.
out.
println("Writing KML file to " + out.
getPath());
al.
writeKml(out.
getPath());
}
al.
writePoly(new File(fileOutputDir, pd.
name +
"-" +
"areas.poly").
getPath());
al.
writeArgsFile(new File(fileOutputDir, pd.
name +
"-" +
"template.args").
getPath(), outputType, pd.
mapId);
}
}
private int getRoundedCoord
(int val
){
int shift =
24 - resolution
;
int half =
1 << (shift -
1); // 0.5 shifted
int mask = ~
((1 << shift
) -
1); // to remove fraction bits
return (val + half
) & mask
;
}
public List<PolygonDesc
> getPolygons
() {
return polygonDescriptions
;
}
}