Rev 3221 |
View as "text/plain" |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2006, 2011.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 or
* version 2 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.mkgmap.reader.osm.boundary;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map.Entry;
import uk.me.parabola.log.Logger;
import uk.me.parabola.mkgmap.build.Locator;
import uk.me.parabola.mkgmap.reader.osm.Element;
import uk.me.parabola.mkgmap.reader.osm.ElementSaver;
import uk.me.parabola.mkgmap.reader.osm.Node;
import uk.me.parabola.mkgmap.reader.osm.OsmConverter;
import uk.me.parabola.mkgmap.reader.osm.Relation;
import uk.me.parabola.mkgmap.reader.osm.Tags;
import uk.me.parabola.mkgmap.reader.osm.Way;
import uk.me.parabola.util.EnhancedProperties;
/**
* This saver only keeps ways with <code>natural=coastline</code> tags. This is
* used for loading of extra coastline files.
*
* @author WanMil
*/
public class BoundaryElementSaver
extends ElementSaver
{
private static final Logger log =
Logger.
getLogger(BoundaryElementSaver.
class);
private final static Locator locator =
new Locator();
private final BoundarySaver saver
;
public BoundaryElementSaver
(EnhancedProperties args, BoundarySaver saver
) {
super(args
);
this.
saver = saver
;
}
/**
* Checks if the given element is an administrative boundary or a
* postal code area.
* @param element an element
* @return <code>true</code> administrative boundary or postal code;
* <code>false</code> element cannot be used for precompiled bounds
*/
public static boolean isBoundary
(Element element
) {
if (element
instanceof Relation) {
String type = element.
getTag("type");
if ("boundary".
equals(type
) ||
"multipolygon".
equals(type
)) {
String boundaryVal = element.
getTag("boundary");
if ("administrative".
equals(boundaryVal
)) {
// for boundary=administrative the admin_level must be set
if (element.
getTag("admin_level") ==
null) {
return false;
}
// Check for admin_level==2 if the name is known in the LocatorConfig.xml.
// This should abandon all non country admin_level 2 boundaries
if (element.
getTag("admin_level").
equals("2")) {
Tags copyTags =
new Tags
();
for (Entry
<String,
String> tag : element.
getTagEntryIterator()) {
copyTags.
put(tag.
getKey(), tag.
getValue());
}
String iso = locator.
getCountryISOCode(copyTags
);
if (iso ==
null) {
log.
warn("Ignore admin_level 2 element:", element.
toBrowseURL(), element.
toTagString());
return false;
}
}
// and a name must be set (check only for a tag containing name
for (Entry
<String,
String> tag : element.
getTagEntryIterator()) {
if (tag.
getKey().
contains("name")) {
return true;
}
}
// does not contain a name tag => do not use it
return false;
} else if ("postal_code".
equals(boundaryVal
)) {
// perform a positive check
// is postal_code set?
if (element.
getTag("postal_code") !=
null) {
return true;
}
// and a name must be set (check only for a tag containing name
for (Entry
<String,
String> tag : element.
getTagEntryIterator()) {
if (tag.
getKey().
contains("name")) {
return true;
}
}
// does not contain a name tag => do not use it
return false;
} else if (element.
getTag("postal_code") !=
null){
return true;
} else {
return false;
}
} else {
return false;
}
} else if (element
instanceof Way
) {
Way w =
(Way
) element
;
// a single way must be closed
if (w.
isClosedInOSM() ==
false) {
return false;
}
// the boundary tag must be "administrative" or "postal_code"
String boundaryVal = element.
getTag("boundary");
if ("administrative".
equals(boundaryVal
)) {
// for boundary=administrative the admin_level must be set
if (element.
getTag("admin_level") ==
null) {
return false;
}
// Check for admin_level==2 if the name is known in the LocatorConfig.xml.
// This should abandon all non country admin_level 2 boundaries
if (element.
getTag("admin_level").
equals("2")) {
Tags copyTags =
new Tags
();
for (Entry
<String,
String> tag : element.
getTagEntryIterator()) {
copyTags.
put(tag.
getKey(), tag.
getValue());
}
String iso = locator.
getCountryISOCode(copyTags
);
if (iso ==
null) {
log.
warn("Ignore admin_level 2 element:", element.
toBrowseURL(), element.
toTagString());
return false;
}
}
// and a name must be set (check only for a tag containing name)
for (Entry
<String,
String> tag : element.
getTagEntryIterator()) {
if (tag.
getKey().
contains("name")) {
return true;
}
}
// does not contain a name tag => do not use it
return false;
} else if ( "postal_code".
equals(boundaryVal
)) {
// the name tag must be set for it
return element.
getTag("name") !=
null;
} else if (element.
getTag("postal_code") !=
null) {
// postal_code as tag
return true;
} else {
return false;
}
} else {
return false;
}
}
public void addRelation
(Relation rel
) {
if (isBoundary
(rel
)) {
BoundaryRelation bRel =
(BoundaryRelation
) createMultiPolyRelation
(rel
);
bRel.
processElements();
Boundary b = bRel.
getBoundary();
if (b
!=
null)
saver.
addBoundary(b
);
} else {
log.
warn("Relation is not processed due to missing tags:", rel.
getId(), rel.
toTagString());
}
}
public void deferRelation
(long id,
Relation rel,
String role
) {
return;
}
public Relation createMultiPolyRelation
(Relation rel
) {
return new BoundaryRelation
(rel, wayMap, getBoundingBox
());
}
public void addNode
(Node node
) {
return;
}
public void convert
(OsmConverter converter
) {
nodeMap =
null;
converter.
setBoundingBox(getBoundingBox
());
ArrayList<Relation> relations =
new ArrayList<Relation>(
relationMap.
values());
relationMap =
null;
Collections.
reverse(relations
);
for (int i = relations.
size() -
1; i
>=
0; i--
) {
converter.
convertRelation(relations.
get(i
));
relations.
remove(i
);
}
for (Way w : wayMap.
values())
converter.
convertWay(w
);
wayMap =
null;
converter.
end();
relationMap =
null;
}
}