Draft implementation
This commit is contained in:
parent
cfa7138ed0
commit
93098a731f
12 changed files with 550 additions and 1017 deletions
|
@ -36,7 +36,6 @@ public class MapRenderingTypes {
|
|||
|
||||
private static final Log log = LogUtil.getLog(MapRenderingTypes.class);
|
||||
|
||||
// TODO Internet access bits for point, polygon
|
||||
/** standard schema :
|
||||
polygon : ll aaaaa ttttt 11 : 14 bits
|
||||
multi : ll aaaaa ttttt 00 : 14 bits
|
||||
|
@ -47,6 +46,7 @@ public class MapRenderingTypes {
|
|||
t - object type, s - subtype
|
||||
*/
|
||||
|
||||
// keep sync ! not change values
|
||||
public final static int MULTY_POLYGON_TYPE = 0;
|
||||
public final static int POLYGON_TYPE = 3;
|
||||
public final static int POLYLINE_TYPE = 2;
|
||||
|
|
|
@ -15,8 +15,11 @@ public class RenderingRuleSearchRequest {
|
|||
|
||||
private List<RenderingRule> searchedScope = new ArrayList<RenderingRule>();
|
||||
|
||||
public final RenderingRuleStorageProperties ALL;
|
||||
|
||||
public RenderingRuleSearchRequest(RenderingRulesStorage storage) {
|
||||
this.storage = storage;
|
||||
this.ALL = storage.PROPS;
|
||||
props = storage.PROPS.getPoperties();
|
||||
values = new int[props.length];
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
|
@ -55,6 +58,14 @@ public class RenderingRuleSearchRequest {
|
|||
System.arraycopy(savedFvalues, 0, fvalues, 0, fvalues.length);
|
||||
}
|
||||
|
||||
public void setInitialTagValueZoom(String tag, String val, int zoom){
|
||||
clearState();
|
||||
setIntFilter(ALL.R_MINZOOM, zoom);
|
||||
setIntFilter(ALL.R_MAXZOOM, zoom);
|
||||
setStringFilter(ALL.R_TAG, tag);
|
||||
setStringFilter(ALL.R_VALUE, val);
|
||||
}
|
||||
|
||||
public boolean isFound() {
|
||||
return searchedScope.size() > 0;
|
||||
}
|
||||
|
@ -174,4 +185,9 @@ public class RenderingRuleSearchRequest {
|
|||
return values[property.getId()];
|
||||
}
|
||||
|
||||
public int getIntPropertyValue(RenderingRuleProperty property, int defValue) {
|
||||
int val = values[property.getId()];
|
||||
return val == -1 ? defValue : val;
|
||||
}
|
||||
|
||||
}
|
|
@ -94,12 +94,13 @@ public class RenderingRuleStorageProperties {
|
|||
R_MAXZOOM = registerRule(RenderingRuleProperty.createInputLessIntProperty(MAXZOOM));
|
||||
R_NIGHT_MODE = registerRule(RenderingRuleProperty.createInputBooleanProperty(NIGHT_MODE));
|
||||
R_LAYER = registerRule(RenderingRuleProperty.createInputIntProperty(LAYER));
|
||||
R_ORDER_TYPE = registerRule(RenderingRuleProperty.createInputStringProperty(ORDER_TYPE));
|
||||
R_ORDER_TYPE = registerRule(RenderingRuleProperty.createInputIntProperty(ORDER_TYPE));
|
||||
R_TEXT_LENGTH = registerRule(RenderingRuleProperty.createInputIntProperty(TEXT_LENGTH));
|
||||
R_REF = registerRule(RenderingRuleProperty.createInputBooleanProperty(REF));
|
||||
|
||||
// order - no sense to make it float
|
||||
R_ORDER = registerRule(RenderingRuleProperty.createOutputIntProperty(ORDER));
|
||||
|
||||
|
||||
// text properties
|
||||
R_TEXT_WRAP_WIDTH = registerRule(RenderingRuleProperty.createOutputIntProperty(TEXT_WRAP_WIDTH));
|
||||
R_TEXT_DY = registerRule(RenderingRuleProperty.createOutputIntProperty(TEXT_DY));
|
||||
|
@ -107,9 +108,8 @@ public class RenderingRuleStorageProperties {
|
|||
R_TEXT_SIZE = registerRule(RenderingRuleProperty.createOutputIntProperty(TEXT_SIZE));
|
||||
R_TEXT_ORDER = registerRule(RenderingRuleProperty.createOutputIntProperty(TEXT_ORDER));
|
||||
R_TEXT_MIN_DISTANCE = registerRule(RenderingRuleProperty.createOutputIntProperty(TEXT_MIN_DISTANCE));
|
||||
R_TEXT_LENGTH = registerRule(RenderingRuleProperty.createOutputIntProperty(TEXT_LENGTH));
|
||||
R_TEXT_SHIELD = registerRule(RenderingRuleProperty.createOutputStringProperty(TEXT_SHIELD));
|
||||
R_REF = registerRule(RenderingRuleProperty.createOutputStringProperty(REF));
|
||||
|
||||
|
||||
R_TEXT_COLOR = registerRule(RenderingRuleProperty.createOutputColorProperty(TEXT_COLOR));
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import javax.xml.parsers.SAXParser;
|
|||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xml.sax.Attributes;
|
||||
|
@ -27,9 +28,10 @@ public class RenderingRulesStorage {
|
|||
|
||||
private final static Log log = LogUtil.getLog(RenderingRulesStorage.class);
|
||||
|
||||
public final static int POINT_RULES = 1;
|
||||
public final static int LINE_RULES = 2;
|
||||
public final static int POLYGON_RULES = 3;
|
||||
// keep sync !
|
||||
public final static int POINT_RULES = MapRenderingTypes.POINT_TYPE;
|
||||
public final static int LINE_RULES = MapRenderingTypes.POLYLINE_TYPE;
|
||||
public final static int POLYGON_RULES = MapRenderingTypes.POLYGON_TYPE;
|
||||
public final static int TEXT_RULES = 4;
|
||||
public final static int ORDER_RULES = 5;
|
||||
private final static int LENGTH_RULES = 6;
|
||||
|
@ -83,6 +85,10 @@ public class RenderingRulesStorage {
|
|||
return bgNightColor;
|
||||
}
|
||||
|
||||
public int getBgColor(boolean nightMode){
|
||||
return nightMode ? bgNightColor : bgColor;
|
||||
}
|
||||
|
||||
public String getDepends() {
|
||||
return depends;
|
||||
}
|
||||
|
@ -107,6 +113,8 @@ public class RenderingRulesStorage {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void registerGlobalRule(RenderingRule rr, int state, Map<String, String> attrsMap) throws SAXException {
|
||||
|
||||
|
||||
int tag = rr.getIntPropertyValue(RenderingRuleStorageProperties.TAG);
|
||||
if(tag == -1){
|
||||
throw new SAXException("Attribute tag should be specified for root filter " + attrsMap.toString());
|
||||
|
@ -168,8 +176,6 @@ public class RenderingRulesStorage {
|
|||
this.parser = parser;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
|
||||
name = parser.isNamespaceAware() ? localName : name;
|
||||
|
@ -272,6 +278,12 @@ public class RenderingRulesStorage {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endDocument() throws SAXException {
|
||||
super.endDocument();
|
||||
System.out.println(""+stack);
|
||||
}
|
||||
|
||||
private Map<String, String> parseAttributes(Attributes attributes, Map<String, String> m) {
|
||||
for (int i = 0; i < attributes.getLength(); i++) {
|
||||
String name = parser.isNamespaceAware() ? attributes.getLocalName(i) : attributes.getQName(i);
|
||||
|
@ -353,19 +365,19 @@ public class RenderingRulesStorage {
|
|||
public static void main(String[] args) throws SAXException, IOException {
|
||||
RenderingRulesStorage storage = new RenderingRulesStorage();
|
||||
storage.parseRulesFromXmlInputStream(RenderingRulesStorage.class.getResourceAsStream("new_default.render.xml"));
|
||||
// storage.printDebug(TEXT_RULES, System.out);
|
||||
// storage.printDebug(POLYGON_RULES, System.out);
|
||||
|
||||
RenderingRuleSearchRequest searchRequest = new RenderingRuleSearchRequest(storage);
|
||||
searchRequest.setStringFilter(storage.PROPS.R_TAG, "highway");
|
||||
searchRequest.setStringFilter(storage.PROPS.R_VALUE, "motorway");
|
||||
searchRequest.setIntFilter(storage.PROPS.R_LAYER, 1);
|
||||
searchRequest.setIntFilter(storage.PROPS.R_MINZOOM, 14);
|
||||
searchRequest.setIntFilter(storage.PROPS.R_MAXZOOM, 14);
|
||||
searchRequest.setStringFilter(storage.PROPS.R_ORDER_TYPE, "line");
|
||||
searchRequest.setBooleanFilter(storage.PROPS.R_NIGHT_MODE, true);
|
||||
searchRequest.setStringFilter(storage.PROPS.R_TAG, "landuse");
|
||||
searchRequest.setStringFilter(storage.PROPS.R_VALUE, "grass");
|
||||
// searchRequest.setIntFilter(storage.PROPS.R_LAYER, 1);
|
||||
searchRequest.setIntFilter(storage.PROPS.R_MINZOOM, 17);
|
||||
searchRequest.setIntFilter(storage.PROPS.R_MAXZOOM, 17);
|
||||
// searchRequest.setStringFilter(storage.PROPS.R_ORDER_TYPE, "line");
|
||||
// searchRequest.setBooleanFilter(storage.PROPS.R_NIGHT_MODE, true);
|
||||
// searchRequest.setBooleanFilter(storage.PROPS.get("hmRendered"), true);
|
||||
|
||||
searchRequest.search(LINE_RULES);
|
||||
searchRequest.search(POLYGON_RULES);
|
||||
printResult(searchRequest, System.out);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,11 +54,14 @@
|
|||
<!-- types : string, int, boolean; possibleValues comma separated possible values for int/string -->
|
||||
<renderingProperty attr="hmRendered" name="All-Purpose Renderer" description="All-Purpose Renderer by Hardy"
|
||||
type="boolean" possibleValues=""/>
|
||||
<renderingProperty attr="appMode" name="Rendering mode" description="Select rendering specific mode"
|
||||
type="string" possibleValues=",car,bicycle,pedestrian"/>
|
||||
|
||||
<!-- input exact layer, orderType check tag, value -->
|
||||
<!-- point = 1, line = 2, polygon = 3 -->
|
||||
<order>
|
||||
<!-- point has order 128 -->
|
||||
<group orderType="polygon">
|
||||
<group orderType="3">
|
||||
<filter tag="building" value="" order="64" />
|
||||
<filter tag="building" value="" layer="-1" order="2" />
|
||||
|
||||
|
@ -79,7 +82,7 @@
|
|||
</group>
|
||||
|
||||
|
||||
<group orderType="line">
|
||||
<group orderType="2">
|
||||
<!-- Below see level -->
|
||||
<filter tag="admin_level" value="0" order="0" />
|
||||
<filter tag="admin_level" value="1" order="0" />
|
||||
|
@ -120,14 +123,14 @@
|
|||
<filter tag="highway" value="bridleway" order="35" />
|
||||
</group>
|
||||
|
||||
<filter tag="" value="" order="128" orderType="point"/>
|
||||
<filter tag="" value="" layer="-1" order="1" orderType="polygon"/>
|
||||
<filter tag="" value="" layer="1" order="64" orderType="polygon"/>
|
||||
<filter tag="" value="" order="1" orderType="polygon"/>
|
||||
<filter tag="" value="" order="128" orderType="1"/>
|
||||
<filter tag="" value="" layer="-1" order="1" orderType="3"/>
|
||||
<filter tag="" value="" layer="1" order="64" orderType="3"/>
|
||||
<filter tag="" value="" order="1" orderType="3"/>
|
||||
|
||||
<filter tag="" value="" layer="-1" order="10" orderType="line"/>
|
||||
<filter tag="" value="" layer="1" order="67" orderType="line"/>
|
||||
<filter tag="" value="" order="11" orderType="line"/>
|
||||
<filter tag="" value="" layer="-1" order="10" orderType="2"/>
|
||||
<filter tag="" value="" layer="1" order="67" orderType="2"/>
|
||||
<filter tag="" value="" order="11" orderType="2"/>
|
||||
|
||||
</order>
|
||||
|
||||
|
@ -135,7 +138,7 @@
|
|||
<!-- PRIORITY Input to filter : tag, value, zoom [minzoom, maxzoom], textLength, ref, textOrder (default=20) -->
|
||||
<text>
|
||||
<!-- Highway ref -->
|
||||
<filter minzoom="10" tag="highway" value="motorway" ref="only" textMinDistance="70" textColor="#ffffff" textSize="12" textBold="true"
|
||||
<filter minzoom="10" tag="highway" value="motorway" ref="true" textMinDistance="70" textColor="#ffffff" textSize="12" textBold="true"
|
||||
textOrder="6">
|
||||
<filter textLength="1" textShield="mot_shield1" />
|
||||
<filter textLength="2" textShield="mot_shield2" />
|
||||
|
@ -145,7 +148,7 @@
|
|||
<filter textLength="6" textShield="mot_shield6" />
|
||||
</filter>
|
||||
|
||||
<filter minzoom="10" tag="highway" value="trunk" ref="only" textMinDistance="70" textColor="#ffffff" textSize="12" textBold="true"
|
||||
<filter minzoom="10" tag="highway" value="trunk" ref="true" textMinDistance="70" textColor="#ffffff" textSize="12" textBold="true"
|
||||
textOrder="6">
|
||||
<filter textLength="1" textShield="tru_shield1" />
|
||||
<filter textLength="2" textShield="tru_shield2" />
|
||||
|
@ -155,7 +158,7 @@
|
|||
<filter textLength="6" textShield="tru_shield6" />
|
||||
</filter>
|
||||
|
||||
<filter minzoom="11" tag="highway" value="primary" ref="only" textMinDistance="70" textColor="#ffffff" textSize="12"
|
||||
<filter minzoom="11" tag="highway" value="primary" ref="true" textMinDistance="70" textColor="#ffffff" textSize="12"
|
||||
textBold="true" textOrder="7">
|
||||
<filter textLength="1" textShield="pri_shield1" />
|
||||
<filter textLength="2" textShield="pri_shield2" />
|
||||
|
@ -165,7 +168,7 @@
|
|||
<filter textLength="6" textShield="pri_shield6" />
|
||||
</filter>
|
||||
|
||||
<filter minzoom="13" tag="highway" value="secondary" ref="only" textMinDistance="70" textColor="#ffffff" textSize="12"
|
||||
<filter minzoom="13" tag="highway" value="secondary" ref="true" textMinDistance="70" textColor="#ffffff" textSize="12"
|
||||
textBold="true" textOrder="8">
|
||||
<filter textLength="1" textShield="sec_shield1" />
|
||||
<filter textLength="2" textShield="sec_shield2" />
|
||||
|
@ -175,7 +178,7 @@
|
|||
<filter textLength="6" textShield="sec_shield6" />
|
||||
</filter>
|
||||
|
||||
<filter minzoom="14" tag="highway" value="tertiary" ref="only" textMinDistance="70" textColor="#ffffff" textSize="12"
|
||||
<filter minzoom="14" tag="highway" value="tertiary" ref="true" textMinDistance="70" textColor="#ffffff" textSize="12"
|
||||
textBold="true" textOrder="9">
|
||||
<filter textLength="1" textShield="ter_shield1" />
|
||||
<filter textLength="2" textShield="ter_shield2" />
|
||||
|
@ -638,11 +641,12 @@
|
|||
</groupFilter>
|
||||
</group>
|
||||
|
||||
<!-- ZM 13 -->
|
||||
<group minzoom="14" strokeWidth_2="0.5" color_2="#b0b0b0" color="#ECECEC">
|
||||
<group >
|
||||
<filter tag="highway" value="service" />
|
||||
<filter tag="highway" value="pedestrian" />
|
||||
<filter tag="highway" value="footway" />
|
||||
<groupFilter minzoom="14" strokeWidth_2="0.5" color_2="#b0b0b0" color="#ECECEC"/>
|
||||
<groupFilter hmRendered="true" minzoom="13" strokeWidth_2="0.5" color_2="#b0b0b0" color="#ECECEC"/>
|
||||
</group>
|
||||
|
||||
<filter minzoom="11" tag="railway" value="station" color="#d4aaaa">
|
||||
|
@ -753,7 +757,7 @@
|
|||
|
||||
<!-- ZM 10 -->
|
||||
<filter minzoom="9" shader="nr" color="#abdf96" tag="leisure" value="nature_reserve">
|
||||
<filter nightMode="true" shader="" color="#000034">
|
||||
<filter nightMode="true" shader="" color="#000034" />
|
||||
</filter>
|
||||
|
||||
<group>
|
||||
|
@ -889,8 +893,8 @@
|
|||
</group>
|
||||
|
||||
|
||||
<filter minzoom="10" color="#a0ffa8a8" tag="landuse" value="military" />
|
||||
<filter nightMode="true" color="#a0560000" >
|
||||
<filter minzoom="10" color="#a0ffa8a8" tag="landuse" value="military">
|
||||
<filter nightMode="true" color="#a0560000" />
|
||||
</filter>
|
||||
|
||||
|
||||
|
@ -901,7 +905,7 @@
|
|||
</filter>
|
||||
|
||||
|
||||
<filter tag="landuse" value="wood" />
|
||||
<filter tag="landuse" value="wood">
|
||||
<filter hmRendered="true">
|
||||
<filter minzoom="10" color="#aed1a0" />
|
||||
</filter>
|
||||
|
@ -980,117 +984,92 @@
|
|||
</groupFilter>
|
||||
</group>
|
||||
|
||||
<!-- TODO START ->
|
||||
<group>
|
||||
<filter tag="highway" value="tertiary" maxzoom="13" />
|
||||
<filter tag="highway" value="tertiary_link" maxzoom="13" />
|
||||
<filter color="#fefeb3" color_2="#fefeb3" shadowColor="#bababa" shadowRadius="1" >
|
||||
<groupFilter color="#fefeb3" color_2="#fefeb3" shadowColor="#bababa">
|
||||
<filter minzoom="10" maxzoom="10" strokeWidth="3" />
|
||||
<filter minzoom="11" maxzoom="11" strokeWidth="4" />
|
||||
<filter minzoom="12" maxzoom="12" strokeWidth="5" />
|
||||
<filter minzoom="13" maxzoom="13" strokeWidth="6" />
|
||||
<switch>
|
||||
<case layer="-1" pathEffect="4_4" />
|
||||
<case /> <!- all other cases ->
|
||||
<filter>
|
||||
<filter minzoom="14" maxzoom="14" strokeWidth="6" />
|
||||
<filter minzoom="15" maxzoom="15" strokeWidth="8" />
|
||||
<filter minzoom="16" maxzoom="16" strokeWidth="10" />
|
||||
<!- radius 0 to avoid showing many black lines, but removed again due to bad visibility on some backgrounds ->
|
||||
<filter minzoom="17" maxzoom="17" strokeWidth="13" />
|
||||
<filter minzoom="18" strokeWidth="18" />
|
||||
</filter>
|
||||
</switch>
|
||||
<!- bridge ->
|
||||
<switch>
|
||||
<case nightMode="false" color="#000000" />
|
||||
<case nightMode="true" color="#ffffff" />
|
||||
<filter layer="1" cap_2="SQUARE" >
|
||||
<filter minzoom="13" maxzoom="14" strokeWidth="8" strokeWidth_2="6" />
|
||||
<filter minzoom="15" maxzoom="15" strokeWidth="10" strokeWidth_2="8" />
|
||||
<filter minzoom="16" maxzoom="16" strokeWidth="12" strokeWidth_2="10" />
|
||||
<filter minzoom="17" maxzoom="17" strokeWidth="15" strokeWidth_2="13" />
|
||||
<filter minzoom="18" strokeWidth="20" strokeWidth_2="18" />
|
||||
</filter>
|
||||
</switch>
|
||||
</filter>
|
||||
</group>
|
||||
|
||||
<switch>
|
||||
<case tag="highway" value="road" />
|
||||
<case tag="highway" value="unclassified" />
|
||||
<case tag="highway" value="residential" />
|
||||
<filter>
|
||||
<switch>
|
||||
<case nightMode="true" color="#9F9F9F" color_2="#9F9F9F" shadowColor="#666666" shadowRadius="1" />
|
||||
<case nightMode="false" color="#ffffff" color_2="#ffffff" shadowColor="#464646" shadowRadius="1" />
|
||||
<filter>
|
||||
<!- ZM <filter minzoom="12" maxzoom="12" strokeWidth="3" /> ->
|
||||
<filter minzoom="13" maxzoom="13" strokeWidth="4" />
|
||||
<switch>
|
||||
<case layer="-1" pathEffect="4_4" />
|
||||
<case /> <!- all other cases ->
|
||||
<filter>
|
||||
<filter minzoom="14" maxzoom="14" strokeWidth="6" />
|
||||
<filter minzoom="15" maxzoom="15" strokeWidth="8" />
|
||||
<filter minzoom="16" maxzoom="16" strokeWidth="10" />
|
||||
<!- radius 0 to avoid showing many black lines, but removed again due to bad visibility on some backgrounds ->
|
||||
<filter minzoom="17" maxzoom="17" strokeWidth="13" />
|
||||
<filter minzoom="18" strokeWidth="18" />
|
||||
</filter>
|
||||
</switch>
|
||||
</filter>
|
||||
</switch>
|
||||
<!- bridge ->
|
||||
<switch>
|
||||
<case nightMode="false" color="#000000" color_2="#ffffff" shadowColor="#464646" />
|
||||
<case nightMode="true" color="#ffffff" color_2="#9F9F9F" shadowColor="#666666" />
|
||||
<filter layer="1" cap_2="SQUARE" >
|
||||
<!-- bridge -->
|
||||
<filter layer="1" cap_2="SQUARE" color="#000000">
|
||||
<filter minzoom="13" maxzoom="14" strokeWidth="8" strokeWidth_2="6" />
|
||||
<filter minzoom="15" maxzoom="15" strokeWidth="10" strokeWidth_2="8" />
|
||||
<filter minzoom="16" maxzoom="16" strokeWidth="12" strokeWidth_2="10" />
|
||||
<filter minzoom="17" maxzoom="17" strokeWidth="15" strokeWidth_2="13" />
|
||||
<filter minzoom="18" strokeWidth="20" strokeWidth_2="18" />
|
||||
<groupFilter nightMode="true" color="#ffffff" />
|
||||
</filter>
|
||||
<filter shadowRadius="1">
|
||||
<filter minzoom="14" maxzoom="14" strokeWidth="6" />
|
||||
<filter minzoom="15" maxzoom="15" strokeWidth="8" />
|
||||
<filter minzoom="16" maxzoom="16" strokeWidth="10" />
|
||||
<!-- radius 0 to avoid showing many black lines, but removed again due to bad visibility on some backgrounds -->
|
||||
<filter minzoom="17" maxzoom="17" strokeWidth="13" />
|
||||
<filter minzoom="18" strokeWidth="18" />
|
||||
<groupFilter layer="-1" pathEffect="4_4"/>
|
||||
</filter>
|
||||
</switch>
|
||||
</filter>
|
||||
</switch>
|
||||
|
||||
<switch>
|
||||
<case tag="highway" value="service" color="#ececec" color_2="#ececec" shadowColor="#b0b0b0" />
|
||||
<case tag="highway" value="living_street" color="#ececec" color_2="#ececec" shadowColor="#b0b0b0" />
|
||||
<case tag="highway" value="pedestrian" color="#ececec" color_2="#ececec" shadowColor="#b0b0b0" />
|
||||
<filter shadowRadius="1">
|
||||
<switch>
|
||||
<case layer="-1" pathEffect="4_4" />
|
||||
<case layer="1" nightMode="false" cap_2="SQUARE" color="#000000" />
|
||||
<case layer="1" nightMode="true" cap_2="SQUARE" color="#000000" />
|
||||
<case /> <!- all other cases ->
|
||||
<filter>
|
||||
<!- ZM <filter minzoom="13" maxzoom="13" strokeWidth="2" />
|
||||
<filter minzoom="14" maxzoom="14" strokeWidth="3" /> ->
|
||||
<object minzoom="15" maxzoom="15" strokeWidth="4">
|
||||
<object layer="1" cap_2="SQUARE" strokeWidth="6" strokeWidth_2="4" />
|
||||
</object>
|
||||
<filter minzoom="16" maxzoom="16" strokeWidth="5" />
|
||||
<filter minzoom="17" maxzoom="17" strokeWidth="8" />
|
||||
<filter minzoom="18" strokeWidth="12"/>
|
||||
</groupFilter>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<filter tag="highway" value="road" />
|
||||
<filter tag="highway" value="unclassified" />
|
||||
<filter tag="highway" value="residential" />
|
||||
<groupFilter>
|
||||
<filter hmRendered="true" minzoom="12" maxzoom="12" strokeWidth="3" />
|
||||
<filter minzoom="13" maxzoom="13" strokeWidth="4" />
|
||||
<!-- bridge -->
|
||||
<filter layer="1" cap_2="SQUARE" color="#000000" color_2="#ffffff" shadowColor="#464646" >
|
||||
<filter minzoom="14" maxzoom="14" strokeWidth="8" strokeWidth_2="6" />
|
||||
<filter minzoom="15" maxzoom="15" strokeWidth="10" strokeWidth_2="8" />
|
||||
<filter minzoom="16" maxzoom="16" strokeWidth="12" strokeWidth_2="10" />
|
||||
<filter minzoom="17" maxzoom="17" strokeWidth="15" strokeWidth_2="13" />
|
||||
<filter minzoom="18" strokeWidth="20" strokeWidth_2="18" />
|
||||
<groupFilter nightMode="true" color="#ffffff" color_2="#9F9F9F" shadowColor="#666666" />
|
||||
</filter>
|
||||
<filter shadowRadius="1" color="#ffffff" color_2="#ffffff" shadowColor="#464646">
|
||||
<filter minzoom="14" maxzoom="14" strokeWidth="6" />
|
||||
<filter minzoom="15" maxzoom="15" strokeWidth="8" />
|
||||
<filter minzoom="16" maxzoom="16" strokeWidth="10" />
|
||||
<!-- radius 0 to avoid showing many black lines, but removed again due to bad visibility on some backgrounds -->
|
||||
<filter minzoom="17" maxzoom="17" strokeWidth="13" />
|
||||
<filter minzoom="18" strokeWidth="18" />
|
||||
<groupFilter layer="-1" pathEffect="4_4"/>
|
||||
<groupFilter nightMode="true" color="#9F9F9F" color_2="#9F9F9F" shadowColor="#666666"/>
|
||||
</filter>
|
||||
</switch>
|
||||
<!- bridge ->
|
||||
<switch>
|
||||
</groupFilter>
|
||||
</group>
|
||||
|
||||
<filter layer="1" cap_2="SQUARE">
|
||||
<!- ZM <filter minzoom="13" maxzoom="14" strokeWidth="5" strokeWidth_2="3" /> ->
|
||||
<group>
|
||||
<filter tag="highway" value="service" color="#ececec" color_2="#ececec" shadowColor="#b0b0b0" />
|
||||
<filter tag="highway" value="living_street" color="#ececec" color_2="#ececec" shadowColor="#b0b0b0" />
|
||||
<filter tag="highway" value="pedestrian" color="#ececec" color_2="#ececec" shadowColor="#b0b0b0" />
|
||||
<groupFilter shadowRadius="1">
|
||||
<filter hmRendered="true" minzoom="13" maxzoom="13" strokeWidth="2" />
|
||||
<filter hmRendered="true" minzoom="14" maxzoom="14" strokeWidth="3" />
|
||||
|
||||
<!-- bridge -->
|
||||
<filter layer="1" cap_2="SQUARE" color="#000000" color_2="#ffffff" shadowColor="#464646" >
|
||||
<filter hmRendered="true" minzoom="13" maxzoom="14" strokeWidth="5" strokeWidth_2="3" />
|
||||
<filter minzoom="15" maxzoom="15" strokeWidth="6" strokeWidth_2="4" />
|
||||
<filter minzoom="16" maxzoom="16" strokeWidth="7" strokeWidth_2="5" />
|
||||
<filter minzoom="17" maxzoom="17" strokeWidth="10" strokeWidth_2="8" />
|
||||
<filter minzoom="18" strokeWidth="14" strokeWidth_2="12" />
|
||||
<groupFilter nightMode="true" color="#000000"/>
|
||||
</filter>
|
||||
<filter shadowRadius="1" color="#ffffff" color_2="#ffffff" shadowColor="#464646">
|
||||
<filter minzoom="15" maxzoom="15" strokeWidth="4" />
|
||||
<filter minzoom="16" maxzoom="16" strokeWidth="5" />
|
||||
<filter minzoom="17" maxzoom="17" strokeWidth="8" />
|
||||
<filter minzoom="18" strokeWidth="12"/>
|
||||
|
||||
<groupFilter layer="-1" pathEffect="4_4"/>
|
||||
</filter>
|
||||
</switch>
|
||||
</filter>
|
||||
</switch>
|
||||
<!- TODO END -->
|
||||
</groupFilter>
|
||||
</group>
|
||||
|
||||
<filter tag="highway" value="cycleway">
|
||||
<filter layer="1" minzoom="14" maxzoom="15" color="#0000ff" strokeWidth="1" pathEffect="2_2" />
|
||||
|
|
|
@ -15,9 +15,9 @@ import net.osmand.osm.LatLon;
|
|||
import net.osmand.plus.activities.ApplicationMode;
|
||||
import net.osmand.plus.activities.OsmandApplication;
|
||||
import net.osmand.plus.activities.search.SearchHistoryHelper;
|
||||
import net.osmand.plus.render.BaseOsmandRender;
|
||||
import net.osmand.plus.render.RendererRegistry;
|
||||
import net.osmand.plus.routing.RouteProvider.RouteService;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
|
@ -143,7 +143,7 @@ public class OsmandSettings {
|
|||
}
|
||||
// update vector renderer
|
||||
RendererRegistry registry = ctx.getRendererRegistry();
|
||||
BaseOsmandRender newRenderer = registry.getRenderer(RENDERER.get());
|
||||
RenderingRulesStorage newRenderer = registry.getRenderer(RENDERER.get());
|
||||
if (newRenderer == null) {
|
||||
newRenderer = registry.defaultRender();
|
||||
}
|
||||
|
@ -1001,7 +1001,7 @@ public class OsmandSettings {
|
|||
if(val == null){
|
||||
val = RendererRegistry.DEFAULT_RENDER;
|
||||
}
|
||||
BaseOsmandRender loaded = ctx.getRendererRegistry().getRenderer(val);
|
||||
RenderingRulesStorage loaded = ctx.getRendererRegistry().getRenderer(val);
|
||||
if (loaded != null) {
|
||||
ctx.getRendererRegistry().setCurrentSelectedRender(loaded);
|
||||
super.setValue(prefs, val);
|
||||
|
@ -1011,10 +1011,12 @@ public class OsmandSettings {
|
|||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
public final CommonPreference<String> RENDERER_APP_NAME = new StringPreference("renderer_appName", "", false);
|
||||
{
|
||||
RENDERER.setModeDefaultValue(ApplicationMode.CAR, RendererRegistry.CAR_RENDER);
|
||||
RENDERER.setModeDefaultValue(ApplicationMode.PEDESTRIAN, RendererRegistry.PEDESTRIAN_RENDER);
|
||||
RENDERER.setModeDefaultValue(ApplicationMode.BICYCLE, RendererRegistry.BICYCLE_RENDER);
|
||||
RENDERER.setModeDefaultValue(ApplicationMode.CAR, "car");
|
||||
RENDERER.setModeDefaultValue(ApplicationMode.PEDESTRIAN, "pedestrian");
|
||||
RENDERER.setModeDefaultValue(ApplicationMode.BICYCLE, "bicycle");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ import net.osmand.plus.AsyncLoadingThread.MapLoadRequest;
|
|||
import net.osmand.plus.AsyncLoadingThread.TileLoadDownloadRequest;
|
||||
import net.osmand.plus.AsyncLoadingThread.TransportLoadRequest;
|
||||
import net.osmand.plus.activities.OsmandApplication;
|
||||
import net.osmand.plus.render.BaseOsmandRender;
|
||||
import net.osmand.plus.render.MapRenderRepositories;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
@ -435,7 +435,7 @@ public class ResourceManager {
|
|||
context.getRendererRegistry().setExternalRenderers(externalRenderers);
|
||||
String r = context.getSettings().RENDERER.get();
|
||||
if(r != null){
|
||||
BaseOsmandRender obj = context.getRendererRegistry().getRenderer(r);
|
||||
RenderingRulesStorage obj = context.getRendererRegistry().getRenderer(r);
|
||||
if(obj != null){
|
||||
context.getRendererRegistry().setCurrentSelectedRender(obj);
|
||||
}
|
||||
|
|
|
@ -160,7 +160,7 @@ public class DownloadFileHelper {
|
|||
fs = toIndex;
|
||||
first = false;
|
||||
} else {
|
||||
String name = entry.getAttrName();
|
||||
String name = entry.getName();
|
||||
// small simplification
|
||||
int ind = name.lastIndexOf('_');
|
||||
if (ind > 0) {
|
||||
|
@ -174,7 +174,7 @@ public class DownloadFileHelper {
|
|||
toIndex = fs;
|
||||
}
|
||||
} else {
|
||||
fs = new File(fileToUnZip, entry.getAttrName());
|
||||
fs = new File(fileToUnZip, entry.getName());
|
||||
}
|
||||
out = new FileOutputStream(fs);
|
||||
int read;
|
||||
|
|
|
@ -1,414 +0,0 @@
|
|||
package net.osmand.plus.render;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.plus.render.OsmandRenderer.RenderingContext;
|
||||
import net.osmand.plus.render.OsmandRenderer.RenderingPaintProperties;
|
||||
import net.osmand.render.OsmandRenderingRulesParser;
|
||||
import net.osmand.render.OsmandRenderingRulesParser.EffectAttributes;
|
||||
import net.osmand.render.OsmandRenderingRulesParser.FilterState;
|
||||
import net.osmand.render.OsmandRenderingRulesParser.RenderingRuleVisitor;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint.Cap;
|
||||
|
||||
|
||||
public class BaseOsmandRender implements RenderingRuleVisitor {
|
||||
|
||||
public String name = "default"; //$NON-NLS-1$
|
||||
public List<String> depends = new ArrayList<String>();
|
||||
public List<BaseOsmandRender> dependRenderers = new ArrayList<BaseOsmandRender>();
|
||||
private static final Log log = LogUtil.getLog(BaseOsmandRender.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Map<String, List<FilterState>>>[] rules = new LinkedHashMap[6];
|
||||
|
||||
|
||||
private int defaultColor;
|
||||
private int defaultNightColor;
|
||||
|
||||
|
||||
public void init(InputStream is) throws IOException, SAXException{
|
||||
long time = System.currentTimeMillis();
|
||||
OsmandRenderingRulesParser parser = new OsmandRenderingRulesParser();
|
||||
parser.parseRenderingRules(is, this);
|
||||
log.info("Init render " + name + " for " + (System.currentTimeMillis() - time) + " ms"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
|
||||
}
|
||||
|
||||
public BaseOsmandRender() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rendering(String name, String depends, int defaultColor, int defaultNightColor) {
|
||||
this.name = name;
|
||||
this.defaultColor = defaultColor;
|
||||
this.defaultNightColor = defaultNightColor;
|
||||
if(depends != null && depends.length() > 0){
|
||||
for(String s : depends.split(",")) { //$NON-NLS-1$
|
||||
if(s.trim().length() > 0){
|
||||
this.depends.add(s.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getDefaultColor(boolean nightMode) {
|
||||
int r = nightMode ? defaultNightColor : defaultColor ;
|
||||
if (r == 0) {
|
||||
for (BaseOsmandRender d : dependRenderers) {
|
||||
r = d.getDefaultColor(nightMode);
|
||||
if (r != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitRule(int state, FilterState filter) {
|
||||
boolean accept = filter.minzoom != -1 || state == OsmandRenderingRulesParser.ORDER_STATE;
|
||||
if(state == OsmandRenderingRulesParser.POINT_STATE){
|
||||
accept &= RenderingIcons.getIcons().containsKey(filter.icon);
|
||||
}
|
||||
if(state == OsmandRenderingRulesParser.ORDER_STATE){
|
||||
accept &= filter.order != 0 && filter.orderType != 0;
|
||||
}
|
||||
if (accept) {
|
||||
if (rules[state] == null) {
|
||||
rules[state] = new LinkedHashMap<String, Map<String, List<FilterState>>>();
|
||||
}
|
||||
if (rules[state].get(filter.tag) == null) {
|
||||
rules[state].put(filter.tag, new LinkedHashMap<String, List<FilterState>>());
|
||||
}
|
||||
if (rules[state].get(filter.tag).get(filter.val) == null) {
|
||||
rules[state].get(filter.tag).put(filter.val, new ArrayList<FilterState>(3));
|
||||
}
|
||||
rules[state].get(filter.tag).get(filter.val).add(filter);
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getPointIcon(String tag, String val, int zoom, boolean nightMode) {
|
||||
Integer i = getPointIconImpl(tag, val, zoom, nightMode);
|
||||
if (i == null) {
|
||||
i = getPointIconImpl(tag, null, zoom, nightMode);
|
||||
}
|
||||
if (i == null) {
|
||||
for (BaseOsmandRender d : dependRenderers) {
|
||||
i = d.getPointIcon(tag, val, zoom, nightMode);
|
||||
if (i != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
// type
|
||||
public float getObjectOrder(String tag, String val, int type, int layer) {
|
||||
if(type == 0){
|
||||
// replace multipolygon with polygon
|
||||
type = 3;
|
||||
}
|
||||
float f = getObjectOrderImpl(tag, val, type, layer);
|
||||
if (f == 0) {
|
||||
f = getObjectOrderImpl(tag, null, type, layer);
|
||||
}
|
||||
if (f == 0) {
|
||||
f = getObjectOrderImpl("", null, type, layer); //$NON-NLS-1$
|
||||
}
|
||||
if(f == 0){
|
||||
for(BaseOsmandRender d : dependRenderers){
|
||||
f = d.getObjectOrder(tag, val, type, layer);
|
||||
if (f != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (f == 0) {
|
||||
if (type == 0 || type == 3) {
|
||||
return 1f;
|
||||
} else if (type == 1) {
|
||||
return 128f;
|
||||
} else {
|
||||
return 35f;
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
public boolean renderPolyline(String tag, String val, int zoom, RenderingContext rc, OsmandRenderer o, int layer, boolean nightMode){
|
||||
boolean r = renderPolylineImpl(tag, val, zoom, rc, o, layer, nightMode);
|
||||
if(!r){
|
||||
r = renderPolylineImpl(tag, null, zoom, rc, o, layer, nightMode);
|
||||
}
|
||||
if(!r){
|
||||
for(BaseOsmandRender d : dependRenderers){
|
||||
r = d.renderPolyline(tag, val, zoom, rc, o, layer, nightMode);
|
||||
if (r) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
public boolean renderPolygon(String tag, String val, int zoom, RenderingContext rc, OsmandRenderer o, boolean nightMode){
|
||||
boolean r = renderPolygonImpl(tag,val, zoom, rc, o, nightMode);
|
||||
if(!r){
|
||||
r = renderPolygonImpl(tag, null, zoom, rc, o, nightMode);
|
||||
}
|
||||
if(!r){
|
||||
for(BaseOsmandRender d : dependRenderers){
|
||||
r = d.renderPolygon(tag, val, zoom, rc, o, nightMode);
|
||||
if (r) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public String renderObjectText(String name, String tag, String val, RenderingContext rc, boolean ref, boolean nightMode) {
|
||||
if(name == null || name.length() == 0){
|
||||
return null;
|
||||
}
|
||||
String ret = renderObjectTextImpl(name, tag, val, rc, ref, nightMode);
|
||||
if(ret == null){
|
||||
ret = renderObjectTextImpl(name, tag, null, rc, ref, nightMode);
|
||||
}
|
||||
if(ret == null){
|
||||
for(BaseOsmandRender d : dependRenderers){
|
||||
ret = d.renderObjectText(name, tag, val, rc, ref, nightMode);
|
||||
if (ret != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean isObjectVisible(String tag, String val, int zoom, int type, boolean nightMode) {
|
||||
if (type == 0) {
|
||||
// replace multipolygon with polygon
|
||||
type = 3;
|
||||
}
|
||||
if (isObjectVisibleImpl(tag, val, zoom, type, nightMode)) {
|
||||
return true;
|
||||
}
|
||||
if (isObjectVisibleImpl(tag, null, zoom, type, nightMode)) {
|
||||
return true;
|
||||
}
|
||||
for (BaseOsmandRender d : dependRenderers) {
|
||||
if (d.isObjectVisible(tag, val, zoom, type, nightMode)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private boolean isObjectVisibleImpl(String tag, String val, int zoom, int type, boolean nightMode) {
|
||||
FilterState fs = findBestFilterState(tag, val, zoom, nightMode, 0, null, 0, rules[type]);
|
||||
return fs != null;
|
||||
}
|
||||
|
||||
private float getObjectOrderImpl(String tag, String val, int type, int layer) {
|
||||
if (rules[OsmandRenderingRulesParser.ORDER_STATE] != null) {
|
||||
Map<String, List<FilterState>> map = rules[OsmandRenderingRulesParser.ORDER_STATE].get(tag);
|
||||
if (map != null) {
|
||||
List<FilterState> list = map.get(val);
|
||||
if (list != null) {
|
||||
int sz = list.size();
|
||||
for (int i = 0; i < sz; i++) {
|
||||
FilterState f = list.get(i);
|
||||
if (f.orderType == type && f.layer == layer) {
|
||||
return f.order;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private Integer getPointIconImpl(String tag, String val, int zoom, boolean nightMode) {
|
||||
FilterState fs = findBestFilterState(tag, val, zoom, nightMode, 0, null, 0, rules[OsmandRenderingRulesParser.POINT_STATE]);
|
||||
if (fs != null) {
|
||||
Integer i = RenderingIcons.getIcons().get(fs.icon);
|
||||
return i == null ? 0 : i;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private FilterState findBestFilterState(String tag, String val, int zoom, boolean nightMode, int layer, Boolean ref,
|
||||
int nameLength, Map<String, Map<String, List<FilterState>>> mapTag) {
|
||||
if (mapTag != null) {
|
||||
Map<String, List<FilterState>> map = mapTag.get(tag);
|
||||
if (map != null) {
|
||||
List<FilterState> list = map.get(val);
|
||||
if (list != null) {
|
||||
FilterState bestResult = null;
|
||||
boolean prevDayNightMatches = false;
|
||||
boolean prevLayerMatches = false;
|
||||
int sz = list.size();
|
||||
for (int i = 0; i < sz; i++) {
|
||||
FilterState f = list.get(i);
|
||||
if (f.minzoom <= zoom && (zoom <= f.maxzoom || f.maxzoom == -1)) {
|
||||
if(ref != null && !checkRefTextRule(f, ref.booleanValue())){
|
||||
continue;
|
||||
}
|
||||
if(f.textLength != nameLength){
|
||||
continue;
|
||||
}
|
||||
boolean dayNightMatches = (f.nightMode != null && f.nightMode.booleanValue() == nightMode) ||
|
||||
(!nightMode && f.nightMode == null);
|
||||
boolean layerMatches = f.layer == layer;
|
||||
boolean defLayerMatches = f.layer == 0;
|
||||
if (dayNightMatches || !prevDayNightMatches){
|
||||
if(dayNightMatches && !prevDayNightMatches){
|
||||
if(layerMatches || defLayerMatches){
|
||||
prevDayNightMatches = true;
|
||||
prevLayerMatches = false;
|
||||
}
|
||||
}
|
||||
if(layerMatches){
|
||||
prevLayerMatches = true;
|
||||
bestResult = f;
|
||||
} else if(defLayerMatches && !prevLayerMatches){
|
||||
bestResult = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean renderPolylineImpl(String tag, String val, int zoom, RenderingContext rc, OsmandRenderer o, int layer, boolean nightMode) {
|
||||
FilterState found = findBestFilterState(tag, val, zoom, nightMode, layer, null, 0, rules[OsmandRenderingRulesParser.LINE_STATE]);
|
||||
if (found != null) {
|
||||
// to not make transparent
|
||||
rc.main.color = Color.BLACK;
|
||||
if (found.shader != null) {
|
||||
Integer i = RenderingIcons.getIcons().get(found.shader);
|
||||
if (i != null) {
|
||||
rc.main.shader = o.getShader(i);
|
||||
}
|
||||
}
|
||||
rc.main.fillArea = false;
|
||||
applyEffectAttributes(found.main, rc.main, o);
|
||||
if (found.effectAttributes.size() > 0) {
|
||||
applyEffectAttributes(found.effectAttributes.get(0), rc.second, o);
|
||||
if (found.effectAttributes.size() > 1) {
|
||||
applyEffectAttributes(found.effectAttributes.get(1), rc.third, o);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean renderPolygonImpl(String tag, String val, int zoom, RenderingContext rc, OsmandRenderer o, boolean nightMode) {
|
||||
FilterState f = findBestFilterState(tag, val, zoom, nightMode, 0, null, 0, rules[OsmandRenderingRulesParser.POLYGON_STATE]);
|
||||
if (f != null) {
|
||||
if (f.shader != null) {
|
||||
Integer i = RenderingIcons.getIcons().get(f.shader);
|
||||
if (i != null) {
|
||||
// to not make transparent
|
||||
rc.main.color = Color.BLACK;
|
||||
rc.main.shader = o.getShader(i);
|
||||
}
|
||||
}
|
||||
rc.main.fillArea = true;
|
||||
applyEffectAttributes(f.main, rc.main, o);
|
||||
if (f.effectAttributes.size() > 0) {
|
||||
applyEffectAttributes(f.effectAttributes.get(0), rc.second, o);
|
||||
if (f.effectAttributes.size() > 1) {
|
||||
applyEffectAttributes(f.effectAttributes.get(1), rc.third, o);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void applyEffectAttributes(EffectAttributes ef, RenderingPaintProperties props, OsmandRenderer o){
|
||||
if(ef.cap != null){
|
||||
props.cap = Cap.valueOf(ef.cap.toUpperCase());
|
||||
}
|
||||
if(ef.color != 0){
|
||||
// do not set transparent color
|
||||
props.color = ef.color;
|
||||
}
|
||||
if(ef.pathEffect != null){
|
||||
props.pathEffect = o.getDashEffect(ef.pathEffect);
|
||||
}
|
||||
if(ef.strokeWidth > 0){
|
||||
props.strokeWidth = ef.strokeWidth;
|
||||
}
|
||||
if(ef.shadowColor != 0 && ef.shadowRadius > 0){
|
||||
props.shadowColor = ef.shadowColor;
|
||||
props.shadowLayer = (int) ef.shadowRadius;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean checkRefTextRule(FilterState f, boolean ref){
|
||||
if(ref){
|
||||
return f.text != null && f.text.ref != null;
|
||||
} else {
|
||||
return f.text == null || f.text.ref == null || "true".equals(f.text.ref); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
private String renderObjectTextImpl(String name, String tag, String val, RenderingContext rc, boolean ref, boolean nightMode) {
|
||||
FilterState fs = findBestFilterState(tag, val, rc.zoom, nightMode, 0, ref, name.length(), rules[OsmandRenderingRulesParser.TEXT_STATE]);
|
||||
if(fs == null){
|
||||
fs = findBestFilterState(tag, val, rc.zoom, nightMode, 0, ref, 0, rules[OsmandRenderingRulesParser.TEXT_STATE]);
|
||||
}
|
||||
if(fs != null){
|
||||
fillTextProperties(fs, rc);
|
||||
return name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void fillTextProperties(FilterState f, RenderingContext rc) {
|
||||
rc.textSize = f.text.textSize;
|
||||
rc.textColor = f.text.textColor == 0 ? Color.BLACK : f.text.textColor;
|
||||
rc.textOrder = f.text.textOrder;
|
||||
rc.textMinDistance = f.text.textMinDistance;
|
||||
rc.showTextOnPath = f.text.textOnPath;
|
||||
Integer i = RenderingIcons.getIcons().get(f.text.textShield);
|
||||
rc.textShield = i== null ? 0 : i.intValue();
|
||||
rc.textWrapWidth = f.text.textWrapWidth;
|
||||
rc.textHaloRadius = f.text.textHaloRadius;
|
||||
rc.textBold = f.text.textBold;
|
||||
rc.textDy = f.text.textDy;
|
||||
}
|
||||
|
||||
public List<String> getDepends() {
|
||||
return depends;
|
||||
}
|
||||
|
||||
public void setDependRenderers(List<BaseOsmandRender> dependRenderers) {
|
||||
this.dependRenderers = dependRenderers;
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.IProgress;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.binary.BinaryMapDataObject;
|
||||
|
@ -35,7 +36,8 @@ import net.osmand.plus.R;
|
|||
import net.osmand.plus.RotatedTileBox;
|
||||
import net.osmand.plus.activities.OsmandApplication;
|
||||
import net.osmand.plus.render.OsmandRenderer.RenderingContext;
|
||||
import net.osmand.render.OsmandRenderingRulesParser;
|
||||
import net.osmand.render.RenderingRuleSearchRequest;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
@ -57,31 +59,31 @@ public class MapRenderRepositories {
|
|||
|
||||
private static String BASEMAP_NAME = "basemap";
|
||||
|
||||
|
||||
// lat/lon box of requested vector data
|
||||
private RectF cObjectsBox = new RectF();
|
||||
// cached objects in order to render rotation without reloading data from db
|
||||
private List<BinaryMapDataObject> cObjects = new LinkedList<BinaryMapDataObject>();
|
||||
|
||||
// currently rendered box (not the same as already rendered)
|
||||
// this box is checked for interrupted process or
|
||||
// this box is checked for interrupted process or
|
||||
private RotatedTileBox requestedBox = null;
|
||||
|
||||
// location of rendered bitmap
|
||||
private RotatedTileBox prevBmpLocation = null;
|
||||
// already rendered bitmap
|
||||
// already rendered bitmap
|
||||
private Bitmap prevBmp;
|
||||
|
||||
// location of rendered bitmap
|
||||
private RotatedTileBox bmpLocation = null;
|
||||
// already rendered bitmap
|
||||
// already rendered bitmap
|
||||
private Bitmap bmp;
|
||||
|
||||
private boolean interrupted = false;
|
||||
private RenderingContext currentRenderingContext;
|
||||
private SearchRequest<BinaryMapDataObject> searchRequest;
|
||||
private OsmandSettings prefs;
|
||||
public MapRenderRepositories(Context context){
|
||||
|
||||
public MapRenderRepositories(Context context) {
|
||||
this.context = context;
|
||||
this.renderer = new OsmandRenderer(context);
|
||||
handler = new Handler(Looper.getMainLooper());
|
||||
|
@ -92,10 +94,9 @@ public class MapRenderRepositories {
|
|||
return context;
|
||||
}
|
||||
|
||||
|
||||
public BinaryMapIndexReader initializeNewResource(final IProgress progress, File file) {
|
||||
long start = System.currentTimeMillis();
|
||||
if(files.containsKey(file.getAbsolutePath())){
|
||||
if (files.containsKey(file.getAbsolutePath())) {
|
||||
closeConnection(files.get(file.getAbsolutePath()), file.getAbsolutePath());
|
||||
}
|
||||
RandomAccessFile raf = null;
|
||||
|
@ -103,14 +104,14 @@ public class MapRenderRepositories {
|
|||
try {
|
||||
raf = new RandomAccessFile(file, "r"); //$NON-NLS-1$
|
||||
reader = new BinaryMapIndexReader(raf);
|
||||
if(reader.getVersion() != IndexConstants.BINARY_MAP_VERSION){
|
||||
if (reader.getVersion() != IndexConstants.BINARY_MAP_VERSION) {
|
||||
return null;
|
||||
}
|
||||
files.put(file.getAbsolutePath(), reader);
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("No connection or unsupported version", e); //$NON-NLS-1$
|
||||
if(raf != null){
|
||||
if (raf != null) {
|
||||
try {
|
||||
raf.close();
|
||||
} catch (IOException e1) {
|
||||
|
@ -118,7 +119,7 @@ public class MapRenderRepositories {
|
|||
}
|
||||
return null;
|
||||
} catch (OutOfMemoryError oome) {
|
||||
if(raf != null){
|
||||
if (raf != null) {
|
||||
try {
|
||||
raf.close();
|
||||
} catch (IOException e1) {
|
||||
|
@ -140,7 +141,7 @@ public class MapRenderRepositories {
|
|||
return prevBmpLocation;
|
||||
}
|
||||
|
||||
protected void closeConnection(BinaryMapIndexReader c, String file){
|
||||
protected void closeConnection(BinaryMapIndexReader c, String file) {
|
||||
files.remove(file);
|
||||
try {
|
||||
c.close();
|
||||
|
@ -160,60 +161,59 @@ public class MapRenderRepositories {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void clearAllResources(){
|
||||
public void clearAllResources() {
|
||||
clearCache();
|
||||
for(String f : new ArrayList<String>(files.keySet())){
|
||||
for (String f : new ArrayList<String>(files.keySet())) {
|
||||
closeConnection(files.get(f), f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean updateMapIsNeeded(RotatedTileBox box){
|
||||
public boolean updateMapIsNeeded(RotatedTileBox box) {
|
||||
if (files.isEmpty() || box == null) {
|
||||
return false;
|
||||
}
|
||||
if(requestedBox == null){
|
||||
if (requestedBox == null) {
|
||||
return true;
|
||||
}
|
||||
if(requestedBox.getZoom() != box.getZoom()){
|
||||
if (requestedBox.getZoom() != box.getZoom()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
float deltaRotate = requestedBox.getRotate() - box.getRotate();
|
||||
if(deltaRotate > 180){
|
||||
if (deltaRotate > 180) {
|
||||
deltaRotate -= 360;
|
||||
} else if(deltaRotate < -180){
|
||||
} else if (deltaRotate < -180) {
|
||||
deltaRotate += 360;
|
||||
}
|
||||
if(Math.abs(deltaRotate) > 25){
|
||||
if (Math.abs(deltaRotate) > 25) {
|
||||
return true;
|
||||
}
|
||||
return !requestedBox.containsTileBox(box);
|
||||
}
|
||||
|
||||
public boolean isEmpty(){
|
||||
public boolean isEmpty() {
|
||||
return files.isEmpty();
|
||||
}
|
||||
|
||||
public void interruptLoadingMap(){
|
||||
public void interruptLoadingMap() {
|
||||
interrupted = true;
|
||||
if(currentRenderingContext != null){
|
||||
if (currentRenderingContext != null) {
|
||||
currentRenderingContext.interrupted = true;
|
||||
}
|
||||
if(searchRequest != null){
|
||||
if (searchRequest != null) {
|
||||
searchRequest.setInterrupted(true);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkWhetherInterrupted(){
|
||||
if(interrupted || (currentRenderingContext != null && currentRenderingContext.interrupted)){
|
||||
private boolean checkWhetherInterrupted() {
|
||||
if (interrupted || (currentRenderingContext != null && currentRenderingContext.interrupted)) {
|
||||
requestedBox = bmpLocation;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean basemapExists(){
|
||||
public boolean basemapExists() {
|
||||
for (String f : files.keySet()) {
|
||||
if (f.toLowerCase().contains(BASEMAP_NAME)) {
|
||||
return true;
|
||||
|
@ -222,7 +222,7 @@ public class MapRenderRepositories {
|
|||
return false;
|
||||
}
|
||||
|
||||
private boolean loadVectorData(RectF dataBox, final int zoom, final BaseOsmandRender renderingType, final boolean nightMode){
|
||||
private boolean loadVectorData(RectF dataBox, final int zoom, final RenderingRuleSearchRequest renderingReq, final boolean nightMode) {
|
||||
double cBottomLatitude = dataBox.bottom;
|
||||
double cTopLatitude = dataBox.top;
|
||||
double cLeftLongitude = dataBox.left;
|
||||
|
@ -256,12 +256,17 @@ public class MapRenderRepositories {
|
|||
int type = types.get(j);
|
||||
int mask = type & 3;
|
||||
TagValuePair pair = root.decodeType(type);
|
||||
if (pair != null && renderingType.isObjectVisible(pair.tag, pair.value, zoom, mask, nightMode)) {
|
||||
return true;
|
||||
}
|
||||
if(pair != null && mask == OsmandRenderingRulesParser.POINT_STATE &&
|
||||
renderingType.isObjectVisible(pair.tag, pair.value, zoom, OsmandRenderingRulesParser.TEXT_STATE, nightMode)){
|
||||
return true;
|
||||
if (pair != null) {
|
||||
renderingReq.setInitialTagValueZoom(pair.tag, pair.value, zoom);
|
||||
if (renderingReq.search(mask)) {
|
||||
return true;
|
||||
}
|
||||
if (mask == RenderingRulesStorage.POINT_RULES) {
|
||||
if (renderingReq.search(RenderingRulesStorage.TEXT_RULES)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -283,10 +288,10 @@ public class MapRenderRepositories {
|
|||
}
|
||||
|
||||
for (String mapName : files.keySet()) {
|
||||
if(basemapSearch && !mapName.toLowerCase().contains(BASEMAP_NAME)){
|
||||
if (basemapSearch && !mapName.toLowerCase().contains(BASEMAP_NAME)) {
|
||||
continue;
|
||||
}
|
||||
BinaryMapIndexReader c = files.get(mapName);
|
||||
BinaryMapIndexReader c = files.get(mapName);
|
||||
searchRequest = BinaryMapIndexReader.buildSearchRequest(leftX, rightX, topY, bottomY, zoom, searchFilter);
|
||||
List<BinaryMapDataObject> res = c.searchMapIndex(searchRequest);
|
||||
for (BinaryMapDataObject r : res) {
|
||||
|
@ -299,12 +304,12 @@ public class MapRenderRepositories {
|
|||
}
|
||||
count++;
|
||||
|
||||
for(int i=0; i < r.getTypes().length; i++){
|
||||
for (int i = 0; i < r.getTypes().length; i++) {
|
||||
if ((r.getTypes()[i] & 0x3) == MapRenderingTypes.MULTY_POLYGON_TYPE) {
|
||||
// multy polygon r.getId() >> 3
|
||||
TagValuePair pair = r.getMapIndex().decodeType(MapRenderingTypes.getMainObjectType(r.getTypes()[i]),
|
||||
MapRenderingTypes.getObjectSubType(r.getTypes()[i]));
|
||||
if(pair != null){
|
||||
if (pair != null) {
|
||||
pair = new TagValuePair(pair.tag, pair.value, r.getTypes()[i]);
|
||||
if (!multiPolygons.containsKey(pair)) {
|
||||
multiPolygons.put(pair, new ArrayList<BinaryMapDataObject>());
|
||||
|
@ -334,34 +339,40 @@ public class MapRenderRepositories {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void validateLatLonBox(RectF box){
|
||||
if(box.top > 90){
|
||||
private void validateLatLonBox(RectF box) {
|
||||
if (box.top > 90) {
|
||||
box.top = 85.5f;
|
||||
}
|
||||
if(box.bottom < -90){
|
||||
if (box.bottom < -90) {
|
||||
box.bottom = -85.5f;
|
||||
}
|
||||
if(box.left <= -180){
|
||||
if (box.left <= -180) {
|
||||
box.left = -179.5f;
|
||||
}
|
||||
if(box.right > 180){
|
||||
if (box.right > 180) {
|
||||
box.right = 180.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void loadMap(RotatedTileBox tileRect, List<IMapDownloaderCallback> notifyList) {
|
||||
interrupted = false;
|
||||
if(currentRenderingContext != null){
|
||||
if (currentRenderingContext != null) {
|
||||
currentRenderingContext = null;
|
||||
}
|
||||
try {
|
||||
// find selected rendering type
|
||||
OsmandApplication app = ((OsmandApplication)context.getApplicationContext());
|
||||
OsmandApplication app = ((OsmandApplication) context.getApplicationContext());
|
||||
Boolean renderDay = app.getDaynightHelper().getDayNightRenderer();
|
||||
boolean nightMode = renderDay != null && !renderDay.booleanValue();
|
||||
// boolean moreDetail = prefs.SHOW_MORE_MAP_DETAIL.get();
|
||||
BaseOsmandRender renderingType = app.getRendererRegistry().getCurrentSelectedRenderer();
|
||||
RenderingRulesStorage storage = app.getRendererRegistry().getCurrentSelectedRenderer();
|
||||
RenderingRuleSearchRequest renderingReq = new RenderingRuleSearchRequest(storage);
|
||||
// TODO pass all global parameters
|
||||
renderingReq.setBooleanFilter(renderingReq.ALL.R_NIGHT_MODE, nightMode);
|
||||
if (renderingReq.ALL.get("appName") != null && !Algoritms.isEmpty(app.getSettings().RENDERER_APP_NAME.get())) {
|
||||
renderingReq.setStringFilter(renderingReq.ALL.get("appName"), app.getSettings().RENDERER_APP_NAME.get());
|
||||
}
|
||||
renderingReq.saveState();
|
||||
|
||||
// prevent editing
|
||||
requestedBox = new RotatedTileBox(tileRect);
|
||||
|
@ -383,7 +394,7 @@ public class MapRenderRepositories {
|
|||
dataBox.bottom -= hi;
|
||||
}
|
||||
validateLatLonBox(dataBox);
|
||||
boolean loaded = loadVectorData(dataBox, requestedBox.getZoom(), renderingType, nightMode);
|
||||
boolean loaded = loadVectorData(dataBox, requestedBox.getZoom(), renderingReq, nightMode);
|
||||
if (!loaded || checkWhetherInterrupted()) {
|
||||
return;
|
||||
}
|
||||
|
@ -406,7 +417,6 @@ public class MapRenderRepositories {
|
|||
|
||||
now = System.currentTimeMillis();
|
||||
|
||||
|
||||
Bitmap bmp = Bitmap.createBitmap(currentRenderingContext.width, currentRenderingContext.height, Config.RGB_565);
|
||||
|
||||
boolean stepByStep = prefs.USE_STEP_BY_STEP_RENDERING.get();
|
||||
|
@ -418,10 +428,8 @@ public class MapRenderRepositories {
|
|||
this.bmpLocation = tileRect;
|
||||
}
|
||||
|
||||
|
||||
|
||||
renderer.generateNewBitmap(currentRenderingContext, cObjects, bmp,
|
||||
prefs.USE_ENGLISH_NAMES.get(), renderingType, stepByStep ? notifyList : null);
|
||||
renderer.generateNewBitmap(currentRenderingContext, cObjects, bmp, prefs.USE_ENGLISH_NAMES.get(), renderingReq,
|
||||
stepByStep ? notifyList : null, storage.getBgColor(nightMode));
|
||||
String renderingDebugInfo = currentRenderingContext.renderingDebugInfo;
|
||||
if (checkWhetherInterrupted()) {
|
||||
currentRenderingContext = null;
|
||||
|
@ -437,13 +445,13 @@ public class MapRenderRepositories {
|
|||
this.prevBmp = null;
|
||||
this.prevBmpLocation = null;
|
||||
}
|
||||
if(prefs.DEBUG_RENDERING_INFO.get()){
|
||||
String timeInfo = "Search done in "+ searchTime+" ms"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
|
||||
if(renderingDebugInfo != null){
|
||||
timeInfo += "\n"+renderingDebugInfo;
|
||||
if (prefs.DEBUG_RENDERING_INFO.get()) {
|
||||
String timeInfo = "Search done in " + searchTime + " ms"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
|
||||
if (renderingDebugInfo != null) {
|
||||
timeInfo += "\n" + renderingDebugInfo;
|
||||
}
|
||||
final String msg = timeInfo;
|
||||
handler.post(new Runnable(){
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
|
||||
|
@ -452,7 +460,7 @@ public class MapRenderRepositories {
|
|||
}
|
||||
} catch (RuntimeException e) {
|
||||
log.error("Runtime memory exception", e); //$NON-NLS-1$
|
||||
handler.post(new Runnable(){
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(context, R.string.rendering_exception, Toast.LENGTH_SHORT).show();
|
||||
|
@ -462,7 +470,7 @@ public class MapRenderRepositories {
|
|||
log.error("Out of memory error", e); //$NON-NLS-1$
|
||||
cObjects = new ArrayList<BinaryMapDataObject>();
|
||||
cObjectsBox = new RectF();
|
||||
handler.post(new Runnable(){
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(context, R.string.rendering_out_of_memory, Toast.LENGTH_SHORT).show();
|
||||
|
@ -481,18 +489,17 @@ public class MapRenderRepositories {
|
|||
return prevBmp;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void clearCache() {
|
||||
cObjects = new ArrayList<BinaryMapDataObject>();
|
||||
cObjectsBox = new RectF();
|
||||
prevBmp = bmp = null;
|
||||
prevBmp = bmp = null;
|
||||
requestedBox = prevBmpLocation = bmpLocation = null;
|
||||
}
|
||||
|
||||
// / Manipulating with multipolygons
|
||||
|
||||
/// Manipulating with multipolygons
|
||||
|
||||
public List<MultyPolygon> proccessMultiPolygons(Map<TagValuePair, List<BinaryMapDataObject>> multyPolygons, int leftX, int rightX, int bottomY, int topY, int zoom){
|
||||
public List<MultyPolygon> proccessMultiPolygons(Map<TagValuePair, List<BinaryMapDataObject>> multyPolygons, int leftX, int rightX,
|
||||
int bottomY, int topY, int zoom) {
|
||||
List<MultyPolygon> listPolygons = new ArrayList<MultyPolygon>(multyPolygons.size());
|
||||
List<TLongList> completedRings = new ArrayList<TLongList>();
|
||||
List<TLongList> incompletedRings = new ArrayList<TLongList>();
|
||||
|
@ -501,7 +508,7 @@ public class MapRenderRepositories {
|
|||
for (TagValuePair type : multyPolygons.keySet()) {
|
||||
List<BinaryMapDataObject> directList;
|
||||
List<BinaryMapDataObject> inverselist;
|
||||
if(((type.additionalAttribute >> 15) & 1) == 1){
|
||||
if (((type.additionalAttribute >> 15) & 1) == 1) {
|
||||
TagValuePair directType = new TagValuePair(type.tag, type.value, type.additionalAttribute & ((1 << 15) - 1));
|
||||
if (!multyPolygons.containsKey(directType)) {
|
||||
inverselist = multyPolygons.get(type);
|
||||
|
@ -522,11 +529,11 @@ public class MapRenderRepositories {
|
|||
incompletedRings.clear();
|
||||
completedRingNames.clear();
|
||||
incompletedRingNames.clear();
|
||||
log.debug("Process multypolygon " + type.tag + " " + type.value + //$NON-NLS-1$ //$NON-NLS-2$
|
||||
" direct list : " +directList + " rev : " + inverselist); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
log.debug("Process multypolygon " + type.tag + " " + type.value + //$NON-NLS-1$ //$NON-NLS-2$
|
||||
" direct list : " + directList + " rev : " + inverselist); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
MultyPolygon pl = processMultiPolygon(leftX, rightX, bottomY, topY, listPolygons, completedRings, incompletedRings,
|
||||
completedRingNames, incompletedRingNames, type, directList, inverselist, zoom);
|
||||
if(pl != null){
|
||||
completedRingNames, incompletedRingNames, type, directList, inverselist, zoom);
|
||||
if (pl != null) {
|
||||
listPolygons.add(pl);
|
||||
}
|
||||
}
|
||||
|
@ -534,8 +541,9 @@ public class MapRenderRepositories {
|
|||
}
|
||||
|
||||
private MultyPolygon processMultiPolygon(int leftX, int rightX, int bottomY, int topY, List<MultyPolygon> listPolygons,
|
||||
List<TLongList> completedRings, List<TLongList> incompletedRings, List<String> completedRingNames, List<String> incompletedRingNames,
|
||||
TagValuePair type, List<BinaryMapDataObject> directList, List<BinaryMapDataObject> inverselist, int zoom) {
|
||||
List<TLongList> completedRings, List<TLongList> incompletedRings, List<String> completedRingNames,
|
||||
List<String> incompletedRingNames, TagValuePair type, List<BinaryMapDataObject> directList,
|
||||
List<BinaryMapDataObject> inverselist, int zoom) {
|
||||
MultyPolygon pl = new MultyPolygon();
|
||||
// delete direction last bit (to not show point)
|
||||
pl.setTag(type.tag);
|
||||
|
@ -564,9 +572,9 @@ public class MapRenderRepositories {
|
|||
y = o.getPoint31YTile(km == 0 ? i : len - i - 1);
|
||||
boolean inside = leftX <= x && x <= rightX && y >= topY && y <= bottomY;
|
||||
boolean lineEnded = calculateLineCoordinates(inside, x, y, pinside, px, py, leftX, rightX, bottomY, topY, coordinates);
|
||||
if(lineEnded){
|
||||
processMultipolygonLine(completedRings, incompletedRings, completedRingNames, incompletedRingNames,
|
||||
coordinates, o.getName());
|
||||
if (lineEnded) {
|
||||
processMultipolygonLine(completedRings, incompletedRings, completedRingNames, incompletedRingNames, coordinates,
|
||||
o.getName());
|
||||
// create new line if it goes outside
|
||||
coordinates = new TLongArrayList();
|
||||
}
|
||||
|
@ -574,19 +582,19 @@ public class MapRenderRepositories {
|
|||
py = y;
|
||||
pinside = inside;
|
||||
}
|
||||
processMultipolygonLine(completedRings, incompletedRings, completedRingNames, incompletedRingNames,
|
||||
coordinates, o.getName());
|
||||
processMultipolygonLine(completedRings, incompletedRings, completedRingNames, incompletedRingNames, coordinates,
|
||||
o.getName());
|
||||
}
|
||||
}
|
||||
if(completedRings.size() == 0 && incompletedRings.size() == 0){
|
||||
if (completedRings.size() == 0 && incompletedRings.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (incompletedRings.size() > 0) {
|
||||
unifyIncompletedRings(incompletedRings, completedRings, completedRingNames, incompletedRingNames, leftX, rightX, bottomY, topY, dbId, zoom);
|
||||
unifyIncompletedRings(incompletedRings, completedRings, completedRingNames, incompletedRingNames, leftX, rightX, bottomY, topY,
|
||||
dbId, zoom);
|
||||
} else {
|
||||
// due to self intersection small objects (for low zooms check only coastline)
|
||||
if (zoom >= 13
|
||||
|| ("natural".equals(type.tag) && "coastline".equals(type.value))) { //$NON-NLS-1$//$NON-NLS-2$
|
||||
if (zoom >= 13 || ("natural".equals(type.tag) && "coastline".equals(type.value))) { //$NON-NLS-1$//$NON-NLS-2$
|
||||
boolean clockwiseFound = false;
|
||||
for (TLongList c : completedRings) {
|
||||
if (isClockwiseWay(c)) {
|
||||
|
@ -622,15 +630,15 @@ public class MapRenderRepositories {
|
|||
}
|
||||
|
||||
// Copied from MapAlgorithms
|
||||
private boolean isClockwiseWay(TLongList c){
|
||||
if(c.size() == 0){
|
||||
private boolean isClockwiseWay(TLongList c) {
|
||||
if (c.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// calculate middle Y
|
||||
int mask = 0xffffffff;
|
||||
long middleY = 0;
|
||||
for(int i=0; i< c.size(); i++) {
|
||||
for (int i = 0; i < c.size(); i++) {
|
||||
middleY += (c.get(i) & mask);
|
||||
}
|
||||
middleY /= (long) c.size();
|
||||
|
@ -671,9 +679,9 @@ public class MapRenderRepositories {
|
|||
}
|
||||
}
|
||||
|
||||
if(firstX != -360){
|
||||
if (firstX != -360) {
|
||||
boolean clockwise = (!firstDirectionUp) == (previousX < firstX);
|
||||
if(clockwise){
|
||||
if (clockwise) {
|
||||
clockwiseSum += Math.abs(previousX - firstX);
|
||||
} else {
|
||||
clockwiseSum -= Math.abs(previousX - firstX);
|
||||
|
@ -687,7 +695,7 @@ public class MapRenderRepositories {
|
|||
private int ray_intersect_x(int prevX, int prevY, int x, int y, int middleY) {
|
||||
// prev node above line
|
||||
// x,y node below line
|
||||
if(prevY > y){
|
||||
if (prevY > y) {
|
||||
int tx = prevX;
|
||||
int ty = prevY;
|
||||
x = prevX;
|
||||
|
@ -712,7 +720,7 @@ public class MapRenderRepositories {
|
|||
}
|
||||
|
||||
// NOT WORKING GOOD !
|
||||
private boolean isClockwiseWayOld(TLongList c){
|
||||
private boolean isClockwiseWayOld(TLongList c) {
|
||||
double angle = 0;
|
||||
double prevAng = 0;
|
||||
int px = 0;
|
||||
|
@ -743,7 +751,6 @@ public class MapRenderRepositories {
|
|||
return angle < 0;
|
||||
}
|
||||
|
||||
|
||||
private void processMultipolygonLine(List<TLongList> completedRings, List<TLongList> incompletedRings,
|
||||
List<String> completedRingsNames, List<String> incompletedRingsNames, TLongList coordinates, String name) {
|
||||
if (coordinates.size() > 0) {
|
||||
|
@ -772,7 +779,7 @@ public class MapRenderRepositories {
|
|||
}
|
||||
if (coordinates.get(0) == coordinates.get(coordinates.size() - 1)) {
|
||||
completedRings.add(coordinates);
|
||||
if(oldName != null){
|
||||
if (oldName != null) {
|
||||
completedRingsNames.add(oldName);
|
||||
} else {
|
||||
completedRingsNames.add(name);
|
||||
|
@ -789,12 +796,11 @@ public class MapRenderRepositories {
|
|||
}
|
||||
}
|
||||
|
||||
private void unifyIncompletedRings(List<TLongList> incompletedRings, List<TLongList> completedRings,
|
||||
List<String> completedRingNames, List<String> incompletedRingNames,
|
||||
int leftX, int rightX, int bottomY, int topY, long dbId, int zoom) {
|
||||
private void unifyIncompletedRings(List<TLongList> incompletedRings, List<TLongList> completedRings, List<String> completedRingNames,
|
||||
List<String> incompletedRingNames, int leftX, int rightX, int bottomY, int topY, long dbId, int zoom) {
|
||||
int mask = 0xffffffff;
|
||||
Set<Integer> nonvisitedRings = new LinkedHashSet<Integer>();
|
||||
for(int j = 0; j< incompletedRings.size(); j++){
|
||||
for (int j = 0; j < incompletedRings.size(); j++) {
|
||||
TLongList i = incompletedRings.get(j);
|
||||
int x = (int) (i.get(i.size() - 1) >> 32);
|
||||
int y = (int) (i.get(i.size() - 1) & mask);
|
||||
|
@ -812,26 +818,24 @@ public class MapRenderRepositories {
|
|||
float dy = (float) MapUtils.get31LatitudeY(y);
|
||||
float dsy = (float) MapUtils.get31LatitudeY(sy);
|
||||
String str;
|
||||
if(!end){
|
||||
if (!end) {
|
||||
str = " Start point (to close) not found : end_x = {0}, end_y = {1}, start_x = {2}, start_y = {3} : bounds {4} {5} - {6} {7}"; //$NON-NLS-1$
|
||||
System.err.println(
|
||||
MessageFormat.format(dbId + str,
|
||||
dx, dy, dsx, dsy, leftX+"", topY+"", rightX+"", bottomY+"")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
|
||||
System.err
|
||||
.println(MessageFormat.format(dbId + str, dx, dy, dsx, dsy, leftX + "", topY + "", rightX + "", bottomY + "")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
|
||||
}
|
||||
if(!st){
|
||||
if (!st) {
|
||||
str = " End not found : end_x = {0}, end_y = {1}, start_x = {2}, start_y = {3} : bounds {4} {5} - {6} {7}"; //$NON-NLS-1$
|
||||
System.err.println(
|
||||
MessageFormat.format(dbId + str,
|
||||
dx, dy, dsx, dsy, leftX+"", topY+"", rightX+"", bottomY+"")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
|
||||
System.err
|
||||
.println(MessageFormat.format(dbId + str, dx, dy, dsx, dsy, leftX + "", topY + "", rightX + "", bottomY + "")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
|
||||
}
|
||||
} else {
|
||||
nonvisitedRings.add(j);
|
||||
}
|
||||
}
|
||||
for(int j = 0; j< incompletedRings.size(); j++){
|
||||
for (int j = 0; j < incompletedRings.size(); j++) {
|
||||
TLongList i = incompletedRings.get(j);
|
||||
String name = incompletedRingNames.get(j);
|
||||
if(!nonvisitedRings.contains(j)){
|
||||
if (!nonvisitedRings.contains(j)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -863,7 +867,7 @@ public class MapRenderRepositories {
|
|||
int csy = (int) (cni.get(0) & mask);
|
||||
if (h % 4 == 0) {
|
||||
// top
|
||||
if (csy == topY && csx >= safelyAddDelta(x, - EVAL_DELTA)) {
|
||||
if (csy == topY && csx >= safelyAddDelta(x, -EVAL_DELTA)) {
|
||||
if (mindiff == UNDEFINED_MIN_DIFF || (csx - x) <= mindiff) {
|
||||
mindiff = (csx - x);
|
||||
nextRingIndex = ni;
|
||||
|
@ -871,7 +875,7 @@ public class MapRenderRepositories {
|
|||
}
|
||||
} else if (h % 4 == 1) {
|
||||
// right
|
||||
if (csx == rightX && csy >= safelyAddDelta(y, - EVAL_DELTA)) {
|
||||
if (csx == rightX && csy >= safelyAddDelta(y, -EVAL_DELTA)) {
|
||||
if (mindiff == UNDEFINED_MIN_DIFF || (csy - y) <= mindiff) {
|
||||
mindiff = (csy - y);
|
||||
nextRingIndex = ni;
|
||||
|
@ -935,17 +939,16 @@ public class MapRenderRepositories {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
completedRings.add(i);
|
||||
completedRingNames.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
private int safelyAddDelta(int number, int delta){
|
||||
private int safelyAddDelta(int number, int delta) {
|
||||
int res = number + delta;
|
||||
if(delta > 0 && res < number){
|
||||
if (delta > 0 && res < number) {
|
||||
return Integer.MAX_VALUE;
|
||||
} else if(delta < 0 && res > number){
|
||||
} else if (delta < 0 && res > number) {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
return res;
|
||||
|
@ -954,8 +957,7 @@ public class MapRenderRepositories {
|
|||
/**
|
||||
* @return -1 if there is no instersection or x<<32 | y
|
||||
*/
|
||||
private long calculateIntersection(int x, int y, int px, int py, int leftX, int rightX,
|
||||
int bottomY, int topY){
|
||||
private long calculateIntersection(int x, int y, int px, int py, int leftX, int rightX, int bottomY, int topY) {
|
||||
int by = -1;
|
||||
int bx = -1;
|
||||
// firstly try to search if the line goes in
|
||||
|
@ -1030,7 +1032,7 @@ public class MapRenderRepositories {
|
|||
|
||||
}
|
||||
|
||||
if(px == rightX || px == leftX || py == topY || py == bottomY){
|
||||
if (px == rightX || px == leftX || py == topY || py == bottomY) {
|
||||
bx = px;
|
||||
by = py;
|
||||
}
|
||||
|
@ -1054,11 +1056,11 @@ public class MapRenderRepositories {
|
|||
}
|
||||
} else {
|
||||
long is = calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY);
|
||||
if(inside){
|
||||
if (inside) {
|
||||
// assert is != -1;
|
||||
coordinates.add(is);
|
||||
coordinates.add((((long) x) << 32) | ((long) y));
|
||||
} else if(is != -1){
|
||||
} else if (is != -1) {
|
||||
int bx = (int) (is >> 32);
|
||||
int by = (int) (is & 0xffffffff);
|
||||
coordinates.add(is);
|
||||
|
@ -1071,7 +1073,6 @@ public class MapRenderRepositories {
|
|||
return lineEnded;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, BinaryMapIndexReader> getMetaInfoFiles() {
|
||||
return files;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package net.osmand.plus.render;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import gnu.trove.map.hash.TFloatObjectHashMap;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -11,12 +11,16 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.binary.BinaryMapDataObject;
|
||||
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
|
||||
import net.osmand.data.MapTileDownloader.IMapDownloaderCallback;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
import net.osmand.osm.MultyPolygon;
|
||||
import net.osmand.render.RenderingRuleProperty;
|
||||
import net.osmand.render.RenderingRuleSearchRequest;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
import net.sf.junidecode.Junidecode;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
@ -86,19 +90,22 @@ public class OsmandRenderer {
|
|||
int shieldRes = 0;
|
||||
int textOrder = 20;
|
||||
|
||||
public void fillProperties(RenderingContext rc, float centerX, float centerY){
|
||||
this.centerX = centerX + rc.textDx;
|
||||
this.centerY = centerY + rc.textDy;
|
||||
textColor = rc.textColor;
|
||||
textSize = rc.textSize;
|
||||
textShadow = (int) rc.textHaloRadius;
|
||||
textWrap = rc.textWrapWidth;
|
||||
bold = rc.textBold;
|
||||
minDistance = rc.textMinDistance;
|
||||
shieldRes = rc.textShield;
|
||||
if(rc.textOrder >= 0){
|
||||
textOrder = rc.textOrder;
|
||||
public void fillProperties(RenderingRuleSearchRequest render, float centerX, float centerY){
|
||||
this.centerX = centerX;
|
||||
this.centerY = centerY + render.getIntPropertyValue(render.ALL.R_TEXT_DY, 0);
|
||||
textColor = render.getIntPropertyValue(render.ALL.R_TEXT_COLOR);
|
||||
if(textColor == 0){
|
||||
textColor = Color.BLACK;
|
||||
}
|
||||
textSize = render.getIntPropertyValue(render.ALL.R_TEXT_SIZE);
|
||||
textShadow = render.getIntPropertyValue(render.ALL.R_TEXT_HALO_RADIUS, 0);
|
||||
textWrap = render.getIntPropertyValue(render.ALL.R_TEXT_WRAP_WIDTH, 0);
|
||||
bold = render.getIntPropertyValue(render.ALL.R_TEXT_BOLD, 0) > 0;
|
||||
minDistance = render.getIntPropertyValue(render.ALL.R_TEXT_MIN_DISTANCE,0);
|
||||
if(render.isSpecified(render.ALL.R_TEXT_SHIELD)) {
|
||||
shieldRes = RenderingIcons.getIcons().get(render.getStringPropertyValue(render.ALL.R_TEXT_SHIELD));
|
||||
}
|
||||
textOrder = render.getIntPropertyValue(render.ALL.R_TEXT_ORDER, 20);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,94 +144,8 @@ public class OsmandRenderer {
|
|||
float cosRotateTileSize;
|
||||
float sinRotateTileSize;
|
||||
|
||||
// These properties are used for rendering one object
|
||||
// polyline props
|
||||
boolean showTextOnPath = false;
|
||||
String showAnotherText = null;
|
||||
float textSize = 0;
|
||||
int textColor = 0;
|
||||
int textMinDistance = 0;
|
||||
int textWrapWidth = 0;
|
||||
float textDx = 0;
|
||||
float textDy = 0;
|
||||
float textHaloRadius = 0;
|
||||
boolean textBold;
|
||||
int textShield = 0;
|
||||
int textOrder = -1;
|
||||
|
||||
String renderingDebugInfo;
|
||||
|
||||
RenderingPaintProperties main = new RenderingPaintProperties();
|
||||
RenderingPaintProperties second = new RenderingPaintProperties();
|
||||
RenderingPaintProperties third = new RenderingPaintProperties();
|
||||
RenderingPaintProperties[] adds = null;
|
||||
|
||||
|
||||
|
||||
public void clearText() {
|
||||
showAnotherText = null;
|
||||
showTextOnPath = false;
|
||||
textSize = 0;
|
||||
textColor = 0;
|
||||
textOrder = -1;
|
||||
textMinDistance = 0;
|
||||
textWrapWidth = 0;
|
||||
textDx = 0;
|
||||
textDy = 0;
|
||||
textHaloRadius = 0;
|
||||
textBold = false;
|
||||
textShield = 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* package*/ static class RenderingPaintProperties {
|
||||
int color;
|
||||
float strokeWidth;
|
||||
int shadowLayer;
|
||||
int shadowColor;
|
||||
boolean fillArea;
|
||||
PathEffect pathEffect;
|
||||
Shader shader;
|
||||
Cap cap;
|
||||
|
||||
public void emptyLine(){
|
||||
color = 0;
|
||||
strokeWidth = 0;
|
||||
cap = Cap.BUTT;
|
||||
pathEffect = null;
|
||||
fillArea = false;
|
||||
shader = null;
|
||||
shadowColor = 0;
|
||||
shadowLayer = 0;
|
||||
}
|
||||
|
||||
public void updatePaint(Paint p){
|
||||
p.setStyle(fillArea ? Style.FILL_AND_STROKE : Style.STROKE);
|
||||
p.setColor(color);
|
||||
p.setShader(shader);
|
||||
if(shadowColor == 0){
|
||||
shadowLayer = 0;
|
||||
}
|
||||
p.setShadowLayer(shadowLayer, 0, 0, shadowColor);
|
||||
p.setStrokeWidth(strokeWidth);
|
||||
p.setStrokeCap(cap);
|
||||
if (!fillArea) {
|
||||
p.setPathEffect(pathEffect);
|
||||
}
|
||||
}
|
||||
|
||||
public void emptyArea(){
|
||||
color = 0;
|
||||
strokeWidth = 0;
|
||||
cap = Cap.BUTT;
|
||||
fillArea = false;
|
||||
shader = null;
|
||||
pathEffect = null;
|
||||
shadowColor = 0;
|
||||
shadowLayer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public OsmandRenderer(Context context) {
|
||||
|
@ -273,7 +194,7 @@ public class OsmandRenderer {
|
|||
return shaders.get(resId);
|
||||
}
|
||||
|
||||
private void put(TFloatObjectHashMap<TIntArrayList> map, Float k, int v, int init){
|
||||
private void put(TIntObjectHashMap<TIntArrayList> map, int k, int v, int init){
|
||||
if(!map.containsKey(k)){
|
||||
map.put(k, new TIntArrayList());
|
||||
}
|
||||
|
@ -282,33 +203,33 @@ public class OsmandRenderer {
|
|||
|
||||
|
||||
public Bitmap generateNewBitmap(RenderingContext rc, List<BinaryMapDataObject> objects, Bitmap bmp, boolean useEnglishNames,
|
||||
BaseOsmandRender renderer, List<IMapDownloaderCallback> notifyList) {
|
||||
RenderingRuleSearchRequest render, List<IMapDownloaderCallback> notifyList, int defaultColor) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
// fill area
|
||||
Canvas cv = new Canvas(bmp);
|
||||
if(renderer != null){
|
||||
int dc = renderer.getDefaultColor(rc.nightMode);
|
||||
if(dc != 0){
|
||||
paintFillEmpty.setColor(dc);
|
||||
}
|
||||
if(defaultColor != 0){
|
||||
paintFillEmpty.setColor(defaultColor);
|
||||
}
|
||||
cv.drawRect(0, 0, bmp.getWidth(), bmp.getHeight(), paintFillEmpty);
|
||||
|
||||
// put in order map
|
||||
int sz = objects.size();
|
||||
int init = sz / 4;
|
||||
TFloatObjectHashMap<TIntArrayList> orderMap = new TFloatObjectHashMap<TIntArrayList>();
|
||||
if (renderer != null) {
|
||||
TIntObjectHashMap<TIntArrayList> orderMap = new TIntObjectHashMap<TIntArrayList>();
|
||||
if (render != null) {
|
||||
for (int i = 0; i < sz; i++) {
|
||||
BinaryMapDataObject o = objects.get(i);
|
||||
int sh = i << 8;
|
||||
|
||||
if (o instanceof MultyPolygon) {
|
||||
int mask = MapRenderingTypes.MULTY_POLYGON_TYPE;
|
||||
int layer = ((MultyPolygon) o).getLayer();
|
||||
put(orderMap, renderer.getObjectOrder(((MultyPolygon) o).getTag(), ((MultyPolygon) o).getValue(),
|
||||
mask, layer), sh, init);
|
||||
render.setInitialTagValueZoom(((MultyPolygon) o).getTag(), ((MultyPolygon) o).getValue(), rc.zoom);
|
||||
render.setIntFilter(render.ALL.R_LAYER, layer);
|
||||
render.setIntFilter(render.ALL.R_ORDER_TYPE, MapRenderingTypes.POLYGON_TYPE);
|
||||
if(render.search(RenderingRulesStorage.ORDER_RULES)) {
|
||||
put(orderMap, render.getIntPropertyValue(render.ALL.R_ORDER), sh, init);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < o.getTypes().length; j++) {
|
||||
// put(orderMap, BinaryMapDataObject.getOrder(o.getTypes()[j]), sh + j, init);
|
||||
|
@ -322,7 +243,12 @@ public class OsmandRenderer {
|
|||
TagValuePair pair = o.getMapIndex().decodeType(MapRenderingTypes.getMainObjectType(wholeType),
|
||||
MapRenderingTypes.getObjectSubType(wholeType));
|
||||
if (pair != null) {
|
||||
put(orderMap, renderer.getObjectOrder(pair.tag, pair.value, mask, layer), sh + j, init);
|
||||
render.setInitialTagValueZoom(pair.tag, pair.value, rc.zoom);
|
||||
render.setIntFilter(render.ALL.R_LAYER, layer);
|
||||
render.setIntFilter(render.ALL.R_ORDER_TYPE, mask);
|
||||
if(render.search(RenderingRulesStorage.ORDER_RULES)) {
|
||||
put(orderMap, render.getIntPropertyValue(render.ALL.R_ORDER), sh, init);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -341,7 +267,7 @@ public class OsmandRenderer {
|
|||
rc.sinRotateTileSize = FloatMath.sin((float) Math.toRadians(rc.rotate)) * TILE_SIZE;
|
||||
|
||||
|
||||
float[] keys = orderMap.keys();
|
||||
int[] keys = orderMap.keys();
|
||||
Arrays.sort(keys);
|
||||
int objCount = 0;
|
||||
for (int k = 0; k < keys.length; k++) {
|
||||
|
@ -353,7 +279,7 @@ public class OsmandRenderer {
|
|||
BinaryMapDataObject obj = objects.get(ind);
|
||||
|
||||
// show text only for main type
|
||||
drawObj(obj, renderer, cv, rc, l, l == 0);
|
||||
drawObj(obj, render, cv, rc, l, l == 0);
|
||||
|
||||
objCount++;
|
||||
}
|
||||
|
@ -647,10 +573,10 @@ public class OsmandRenderer {
|
|||
}
|
||||
|
||||
|
||||
protected void drawObj(BinaryMapDataObject obj, BaseOsmandRender render, Canvas canvas, RenderingContext rc, int l, boolean renderText) {
|
||||
protected void drawObj(BinaryMapDataObject obj, RenderingRuleSearchRequest render, Canvas canvas, RenderingContext rc, int l, boolean renderText) {
|
||||
rc.allObjects++;
|
||||
if (obj instanceof MultyPolygon) {
|
||||
drawMultiPolygon(obj, render,canvas, rc);
|
||||
drawMultiPolygon(obj, render, canvas, rc);
|
||||
} else {
|
||||
int mainType = obj.getTypes()[l];
|
||||
int t = mainType & 3;
|
||||
|
@ -707,28 +633,20 @@ public class OsmandRenderer {
|
|||
return rc.tempPoint;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void clearCachedResources(){
|
||||
cachedIcons.clear();
|
||||
shaders.clear();
|
||||
}
|
||||
|
||||
private void drawMultiPolygon(BinaryMapDataObject obj, BaseOsmandRender render, Canvas canvas, RenderingContext rc) {
|
||||
private void drawMultiPolygon(BinaryMapDataObject obj, RenderingRuleSearchRequest render, Canvas canvas, RenderingContext rc) {
|
||||
String tag = ((MultyPolygon)obj).getTag();
|
||||
String value = ((MultyPolygon)obj).getValue();
|
||||
if(render == null || tag == null){
|
||||
return;
|
||||
}
|
||||
rc.main.emptyArea();
|
||||
rc.second.emptyLine();
|
||||
rc.main.color = Color.rgb(245, 245, 245);
|
||||
|
||||
boolean rendered = render.renderPolygon(tag, value, rc.zoom, rc, this, rc.nightMode);
|
||||
if(!rendered){
|
||||
render.setInitialTagValueZoom(tag, value, rc.zoom);
|
||||
boolean rendered = render.search(RenderingRulesStorage.POLYGON_RULES);
|
||||
if(!rendered || !updatePaint(render, paint, 0, true)){
|
||||
return;
|
||||
}
|
||||
rc.visible++;
|
||||
|
@ -754,21 +672,16 @@ public class OsmandRenderer {
|
|||
}
|
||||
}
|
||||
}
|
||||
rc.main.updatePaint(paint);
|
||||
canvas.drawPath(path, paint);
|
||||
// for test purpose
|
||||
// rc.second.strokeWidth = 1.5f;
|
||||
// rc.second.color = Color.BLACK;
|
||||
|
||||
if (rc.second.strokeWidth != 0) {
|
||||
rc.second.updatePaint(paint);
|
||||
// render.strokeWidth = 1.5f;
|
||||
// render.color = Color.BLACK;
|
||||
if (updatePaint(render, paint, 1, false)) {
|
||||
canvas.drawPath(path, paint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void drawPolygon(BinaryMapDataObject obj, BaseOsmandRender render, Canvas canvas, RenderingContext rc, TagValuePair pair) {
|
||||
|
||||
private void drawPolygon(BinaryMapDataObject obj, RenderingRuleSearchRequest render, Canvas canvas, RenderingContext rc, TagValuePair pair) {
|
||||
if(render == null || pair == null){
|
||||
return;
|
||||
}
|
||||
|
@ -776,12 +689,11 @@ public class OsmandRenderer {
|
|||
float yText = 0;
|
||||
int zoom = rc.zoom;
|
||||
Path path = null;
|
||||
rc.main.emptyArea();
|
||||
rc.second.emptyLine();
|
||||
// rc.main.color = Color.rgb(245, 245, 245);
|
||||
|
||||
boolean rendered = render.renderPolygon(pair.tag, pair.value, zoom, rc, this, rc.nightMode);
|
||||
if(!rendered){
|
||||
// rc.main.color = Color.rgb(245, 245, 245);
|
||||
render.setInitialTagValueZoom(pair.tag, pair.value, zoom);
|
||||
boolean rendered = render.search(RenderingRulesStorage.POLYGON_RULES);
|
||||
if(!rendered || !updatePaint(render, paint, 0, true)){
|
||||
return;
|
||||
}
|
||||
rc.visible++;
|
||||
|
@ -800,11 +712,8 @@ public class OsmandRenderer {
|
|||
}
|
||||
|
||||
if (path != null && len > 0) {
|
||||
|
||||
rc.main.updatePaint(paint);
|
||||
canvas.drawPath(path, paint);
|
||||
if (rc.second.strokeWidth != 0) {
|
||||
rc.second.updatePaint(paint);
|
||||
if (updatePaint(render, paint, 1, false)) {
|
||||
canvas.drawPath(path, paint);
|
||||
}
|
||||
String name = obj.getName();
|
||||
|
@ -812,11 +721,81 @@ public class OsmandRenderer {
|
|||
drawPointText(render, rc, pair, xText / len, yText / len, name);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private void drawPointText(BaseOsmandRender render, RenderingContext rc, TagValuePair pair, float xText, float yText, String name) {
|
||||
rc.clearText();
|
||||
private boolean updatePaint(RenderingRuleSearchRequest req, Paint p, int ind, boolean area){
|
||||
RenderingRuleProperty rColor;
|
||||
RenderingRuleProperty rStrokeW;
|
||||
RenderingRuleProperty rCap;
|
||||
RenderingRuleProperty rPathEff;
|
||||
if(ind == 0){
|
||||
rColor = req.ALL.R_COLOR;
|
||||
rStrokeW = req.ALL.R_STROKE_WIDTH;
|
||||
rCap = req.ALL.R_CAP;
|
||||
rPathEff = req.ALL.R_PATH_EFFECT;
|
||||
} else if(ind == 1){
|
||||
rColor = req.ALL.R_COLOR_2;
|
||||
rStrokeW = req.ALL.R_STROKE_WIDTH_2;
|
||||
rCap = req.ALL.R_CAP_2;
|
||||
rPathEff = req.ALL.R_PATH_EFFECT_2;
|
||||
} else {
|
||||
rColor = req.ALL.R_COLOR_3;
|
||||
rStrokeW = req.ALL.R_STROKE_WIDTH_3;
|
||||
rCap = req.ALL.R_CAP_3;
|
||||
rPathEff = req.ALL.R_PATH_EFFECT_3;
|
||||
}
|
||||
if(area){
|
||||
if(!req.isSpecified(rColor) && !req.isSpecified(req.ALL.R_SHADER)){
|
||||
return false;
|
||||
}
|
||||
p.setStyle(Style.FILL_AND_STROKE);
|
||||
p.setStrokeWidth(0);
|
||||
} else {
|
||||
if(!req.isSpecified(rStrokeW)){
|
||||
return false;
|
||||
}
|
||||
p.setStyle(Style.STROKE);
|
||||
p.setStrokeWidth(req.getFloatPropertyValue(rStrokeW));
|
||||
String cap = req.getStringPropertyValue(rCap);
|
||||
if(!Algoritms.isEmpty(cap)){
|
||||
p.setStrokeCap(Cap.valueOf(cap.toUpperCase()));
|
||||
} else {
|
||||
p.setStrokeCap(Cap.BUTT);
|
||||
}
|
||||
String pathEffect = req.getStringPropertyValue(rPathEff);
|
||||
if (!Algoritms.isEmpty(pathEffect)) {
|
||||
p.setPathEffect(getDashEffect(pathEffect));
|
||||
} else {
|
||||
p.setPathEffect(null);
|
||||
}
|
||||
}
|
||||
p.setColor(req.getIntPropertyValue(rColor));
|
||||
|
||||
if(ind == 0){
|
||||
Integer resId = RenderingIcons.getIcons().get(req.getStringPropertyValue(req.ALL.R_SHADER));
|
||||
if(resId != null){
|
||||
p.setColor(Color.BLACK);
|
||||
p.setShader(getShader(resId));
|
||||
} else {
|
||||
p.setShader(null);
|
||||
}
|
||||
|
||||
int shadowColor = req.getIntPropertyValue(req.ALL.R_SHADOW_COLOR);
|
||||
int shadowLayer = req.getIntPropertyValue(req.ALL.R_SHADOW_RADIUS);
|
||||
if(shadowColor == 0){
|
||||
shadowLayer = 0;
|
||||
}
|
||||
p.setShadowLayer(shadowLayer, 0, 0, shadowColor);
|
||||
} else {
|
||||
p.setShader(null);
|
||||
p.setShadowLayer(0, 0, 0, 0);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void drawPointText(RenderingRuleSearchRequest render, RenderingContext rc, TagValuePair pair, float xText, float yText, String name) {
|
||||
String ref = null;
|
||||
if (name.charAt(0) == MapRenderingTypes.REF_CHAR) {
|
||||
ref = name.substring(1);
|
||||
|
@ -833,28 +812,35 @@ public class OsmandRenderer {
|
|||
}
|
||||
|
||||
if (ref != null && ref.trim().length() > 0) {
|
||||
rc.clearText();
|
||||
ref = render.renderObjectText(ref, pair.tag, pair.value, rc, true, rc.nightMode);
|
||||
TextDrawInfo text = new TextDrawInfo(ref);
|
||||
text.fillProperties(rc, xText, yText);
|
||||
rc.textToDraw.add(text);
|
||||
render.setInitialTagValueZoom(pair.tag, pair.value, rc.zoom);
|
||||
render.setIntFilter(render.ALL.R_TEXT_LENGTH, ref.length());
|
||||
render.setBooleanFilter(render.ALL.R_REF, true);
|
||||
if(render.search(RenderingRulesStorage.TEXT_RULES)){
|
||||
TextDrawInfo text = new TextDrawInfo(ref);
|
||||
text.fillProperties(render, xText, yText);
|
||||
rc.textToDraw.add(text);
|
||||
}
|
||||
|
||||
}
|
||||
name = render.renderObjectText(name, pair.tag, pair.value, rc, false, rc.nightMode);
|
||||
if (rc.textSize > 0 && name != null) {
|
||||
render.setInitialTagValueZoom(pair.tag, pair.value, rc.zoom);
|
||||
render.setIntFilter(render.ALL.R_TEXT_LENGTH, name.length());
|
||||
render.setBooleanFilter(render.ALL.R_REF, true);
|
||||
if(render.search(RenderingRulesStorage.TEXT_RULES)){
|
||||
TextDrawInfo info = new TextDrawInfo(name);
|
||||
info.fillProperties(rc, xText, yText);
|
||||
info.fillProperties(render, xText, yText);
|
||||
rc.textToDraw.add(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void drawPoint(BinaryMapDataObject obj, BaseOsmandRender render, Canvas canvas, RenderingContext rc, TagValuePair pair, boolean renderText) {
|
||||
private void drawPoint(BinaryMapDataObject obj, RenderingRuleSearchRequest render, Canvas canvas, RenderingContext rc, TagValuePair pair, boolean renderText) {
|
||||
if(render == null || pair == null){
|
||||
return;
|
||||
}
|
||||
render.setInitialTagValueZoom(pair.tag, pair.value, rc.zoom);
|
||||
render.search(RenderingRulesStorage.POINT_RULES);
|
||||
|
||||
Integer resId = render.getPointIcon(pair.tag, pair.value, rc.zoom, rc.nightMode);
|
||||
Integer resId = RenderingIcons.getIcons().get(render.getStringPropertyValue(render.ALL.R_ICON));
|
||||
String name = null;
|
||||
if (renderText) {
|
||||
name = obj.getName();
|
||||
|
@ -890,7 +876,7 @@ public class OsmandRenderer {
|
|||
|
||||
|
||||
|
||||
private void drawPolyline(BinaryMapDataObject obj, BaseOsmandRender render, Canvas canvas, RenderingContext rc, TagValuePair pair, int layer) {
|
||||
private void drawPolyline(BinaryMapDataObject obj, RenderingRuleSearchRequest render, Canvas canvas, RenderingContext rc, TagValuePair pair, int layer) {
|
||||
if(render == null || pair == null){
|
||||
return;
|
||||
}
|
||||
|
@ -898,16 +884,15 @@ public class OsmandRenderer {
|
|||
if(length < 2){
|
||||
return;
|
||||
}
|
||||
rc.main.emptyLine();
|
||||
rc.second.emptyLine();
|
||||
rc.third.emptyLine();
|
||||
rc.adds = null;
|
||||
boolean res = render.renderPolyline(pair.tag, pair.value, rc.zoom, rc, this, layer, rc.nightMode);
|
||||
if(rc.main.strokeWidth == 0 || !res){
|
||||
render.setInitialTagValueZoom(pair.tag, pair.value, rc.zoom);
|
||||
render.setIntFilter(render.ALL.R_LAYER, layer);
|
||||
boolean rendered = render.search(RenderingRulesStorage.LINE_RULES);
|
||||
if(!rendered || !updatePaint(render, paint, 0, false)){
|
||||
return;
|
||||
}
|
||||
boolean oneway = false;
|
||||
if(rc.zoom >= 16 && "highway".equals(pair.tag) && MapRenderingTypes.isOneWayWay(obj.getHighwayAttributes())){ //$NON-NLS-1$
|
||||
rc.adds = getOneWayProperties();
|
||||
oneway = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -953,20 +938,17 @@ public class OsmandRenderer {
|
|||
yPrev = p.y;
|
||||
}
|
||||
if (path != null) {
|
||||
rc.main.updatePaint(paint);
|
||||
canvas.drawPath(path, paint);
|
||||
if (rc.second.strokeWidth != 0) {
|
||||
rc.second.updatePaint(paint);
|
||||
if (updatePaint(render, paint, 1, false)) {
|
||||
canvas.drawPath(path, paint);
|
||||
if (rc.third.strokeWidth != 0) {
|
||||
rc.third.updatePaint(paint);
|
||||
if (updatePaint(render, paint, 2, false)) {
|
||||
canvas.drawPath(path, paint);
|
||||
}
|
||||
}
|
||||
if (rc.adds != null) {
|
||||
for (int i = 0; i < rc.adds.length; i++) {
|
||||
rc.adds[i].updatePaint(paint);
|
||||
canvas.drawPath(path, paint);
|
||||
if(oneway){
|
||||
Paint[] paints = getOneWayPaints();
|
||||
for (int i = 0; i < paints.length; i++) {
|
||||
canvas.drawPath(path, paints[i]);
|
||||
}
|
||||
}
|
||||
if (obj.getName() != null && obj.getName().length() > 0) {
|
||||
|
@ -986,22 +968,26 @@ public class OsmandRenderer {
|
|||
}
|
||||
}
|
||||
if(ref != null && ref.trim().length() > 0){
|
||||
rc.clearText();
|
||||
ref = render.renderObjectText(ref, pair.tag, pair.value, rc, true, rc.nightMode);
|
||||
TextDrawInfo text = new TextDrawInfo(ref);
|
||||
text.fillProperties(rc, middlePoint.x, middlePoint.y);
|
||||
text.pathRotate = pathRotate;
|
||||
rc.textToDraw.add(text);
|
||||
render.setInitialTagValueZoom(pair.tag, pair.value, rc.zoom);
|
||||
render.setIntFilter(render.ALL.R_TEXT_LENGTH, ref.length());
|
||||
render.setBooleanFilter(render.ALL.R_REF, true);
|
||||
if(render.search(RenderingRulesStorage.TEXT_RULES)){
|
||||
TextDrawInfo text = new TextDrawInfo(ref);
|
||||
text.fillProperties(render, middlePoint.x, middlePoint.y);
|
||||
text.pathRotate = pathRotate;
|
||||
rc.textToDraw.add(text);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(name != null && name.trim().length() > 0){
|
||||
rc.clearText();
|
||||
name = render.renderObjectText(name, pair.tag, pair.value, rc, false, rc.nightMode);
|
||||
if (rc.textSize > 0) {
|
||||
render.setInitialTagValueZoom(pair.tag, pair.value, rc.zoom);
|
||||
render.setIntFilter(render.ALL.R_TEXT_LENGTH, name.length());
|
||||
render.setBooleanFilter(render.ALL.R_REF, false);
|
||||
if (render.search(RenderingRulesStorage.TEXT_RULES)) {
|
||||
TextDrawInfo text = new TextDrawInfo(name);
|
||||
if (!rc.showTextOnPath) {
|
||||
text.fillProperties(rc, middlePoint.x, middlePoint.y);
|
||||
if (render.getIntPropertyValue(render.ALL.R_TEXT_ON_PATH, 0) == 0) {
|
||||
text.fillProperties(render, middlePoint.x, middlePoint.y);
|
||||
rc.textToDraw.add(text);
|
||||
} else {
|
||||
paintText.setTextSize(text.textSize);
|
||||
|
@ -1019,10 +1005,11 @@ public class OsmandRenderer {
|
|||
}
|
||||
}
|
||||
}
|
||||
text.fillProperties(rc, xMid / 2, yMid / 2);
|
||||
text.fillProperties(render, xMid / 2, yMid / 2);
|
||||
text.pathRotate = pathRotate;
|
||||
text.drawOnPath = path;
|
||||
text.vOffset = rc.main.strokeWidth / 2 - 1;
|
||||
float strokeWidth = render.getFloatPropertyValue(render.ALL.R_STROKE_WIDTH);
|
||||
text.vOffset = strokeWidth / 2 - 1;
|
||||
rc.textToDraw.add(text);
|
||||
}
|
||||
}
|
||||
|
@ -1032,37 +1019,36 @@ public class OsmandRenderer {
|
|||
}
|
||||
}
|
||||
}
|
||||
private static RenderingPaintProperties[] oneWay = null;
|
||||
public static RenderingPaintProperties[] getOneWayProperties(){
|
||||
private static Paint[] oneWay = null;
|
||||
private static Paint oneWayPaint(){
|
||||
Paint oneWay = new Paint();
|
||||
oneWay.setStyle(Style.STROKE);
|
||||
oneWay.setColor(0xff6c70d5);
|
||||
oneWay.setAntiAlias(true);
|
||||
return oneWay;
|
||||
}
|
||||
public static Paint[] getOneWayPaints(){
|
||||
if(oneWay == null){
|
||||
PathEffect arrowDashEffect1 = new DashPathEffect(new float[] { 0, 12, 10, 152 }, 0);
|
||||
PathEffect arrowDashEffect2 = new DashPathEffect(new float[] { 0, 12, 9, 153 }, 1);
|
||||
PathEffect arrowDashEffect3 = new DashPathEffect(new float[] { 0, 18, 2, 154 }, 1);
|
||||
PathEffect arrowDashEffect4 = new DashPathEffect(new float[] { 0, 18, 1, 155 }, 1);
|
||||
oneWay = new RenderingPaintProperties[4];
|
||||
oneWay[0] = new RenderingPaintProperties();
|
||||
oneWay[0].emptyLine();
|
||||
oneWay[0].color = 0xff6c70d5;
|
||||
oneWay[0].strokeWidth = 1;
|
||||
oneWay[0].pathEffect = arrowDashEffect1;
|
||||
oneWay = new Paint[4];
|
||||
oneWay[0] = oneWayPaint();
|
||||
oneWay[0].setStrokeWidth(1);
|
||||
oneWay[0].setPathEffect(arrowDashEffect1);
|
||||
|
||||
oneWay[1] = new RenderingPaintProperties();
|
||||
oneWay[1].emptyLine();
|
||||
oneWay[1].color = 0xff6c70d5;
|
||||
oneWay[1].strokeWidth = 2;
|
||||
oneWay[1].pathEffect = arrowDashEffect2;
|
||||
oneWay[1] = oneWayPaint();
|
||||
oneWay[1].setStrokeWidth(2);
|
||||
oneWay[1].setPathEffect(arrowDashEffect2);
|
||||
|
||||
oneWay[2] = new RenderingPaintProperties();
|
||||
oneWay[2].emptyLine();
|
||||
oneWay[2].color = 0xff6c70d5;
|
||||
oneWay[2].strokeWidth = 3;
|
||||
oneWay[2].pathEffect = arrowDashEffect3;
|
||||
oneWay[2] = oneWayPaint();
|
||||
oneWay[2].setStrokeWidth(3);
|
||||
oneWay[2].setPathEffect(arrowDashEffect3);
|
||||
|
||||
oneWay[3] = new RenderingPaintProperties();
|
||||
oneWay[3].emptyLine();
|
||||
oneWay[3].color = 0xff6c70d5;
|
||||
oneWay[3].strokeWidth = 4;
|
||||
oneWay[3].pathEffect = arrowDashEffect4;
|
||||
oneWay[3] = oneWayPaint();
|
||||
oneWay[3].setStrokeWidth(4);
|
||||
oneWay[3].setPathEffect(arrowDashEffect4);
|
||||
|
||||
}
|
||||
return oneWay;
|
||||
|
|
|
@ -4,16 +4,15 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.render.OsmandRenderingRulesParser;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xml.sax.SAXException;
|
||||
|
@ -24,72 +23,27 @@ public class RendererRegistry {
|
|||
private final static Log log = LogUtil.getLog(RendererRegistry.class);
|
||||
|
||||
public final static String DEFAULT_RENDER = "default"; //$NON-NLS-1$
|
||||
public final static String CAR_RENDER = "car"; //$NON-NLS-1$
|
||||
public final static String BICYCLE_RENDER = "bicycle"; //$NON-NLS-1$
|
||||
public final static String PEDESTRIAN_RENDER = "pedestrian"; //$NON-NLS-1$
|
||||
|
||||
|
||||
|
||||
public RendererRegistry(){
|
||||
internalRenderers.put(DEFAULT_RENDER, "default.render.xml"); //$NON-NLS-1$
|
||||
internalRenderers.put(CAR_RENDER, "car.render.xml"); //$NON-NLS-1$
|
||||
internalRenderers.put(BICYCLE_RENDER, "bicycle.render.xml"); //$NON-NLS-1$
|
||||
internalRenderers.put(PEDESTRIAN_RENDER, "pedestrian.render.xml"); //$NON-NLS-1$
|
||||
internalRenderers.put("all-purpose (more detail)", "all-purpose.render.xml"); //$NON-NLS-1$
|
||||
internalRenderers.put("bicycle (more detail)", "bicycle-all.render.xml"); //$NON-NLS-1$
|
||||
internalRenderers.put("pedestrian (more detail)", "pedestrian-all.render.xml"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
private BaseOsmandRender defaultRender = null;
|
||||
private BaseOsmandRender currentSelectedRender = null;
|
||||
private RenderingRulesStorage defaultRender = null;
|
||||
private RenderingRulesStorage currentSelectedRender = null;
|
||||
|
||||
private Map<String, File> externalRenderers = new LinkedHashMap<String, File>();
|
||||
private Map<String, String> internalRenderers = new LinkedHashMap<String, String>();
|
||||
|
||||
private Map<String, BaseOsmandRender> renderers = new LinkedHashMap<String, BaseOsmandRender>();
|
||||
private Map<String, RenderingRulesStorage> renderers = new LinkedHashMap<String, RenderingRulesStorage>();
|
||||
|
||||
public BaseOsmandRender defaultRender() {
|
||||
public RendererRegistry(){
|
||||
internalRenderers.put(DEFAULT_RENDER, "new_default.render.xml");
|
||||
}
|
||||
|
||||
public RenderingRulesStorage defaultRender() {
|
||||
if(defaultRender == null){
|
||||
defaultRender = getRenderer(DEFAULT_RENDER);
|
||||
if (defaultRender == null) {
|
||||
try {
|
||||
defaultRender = new BaseOsmandRender();
|
||||
defaultRender.init(OsmandRenderingRulesParser.class.getResourceAsStream("default.render.xml")); //$NON-NLS-1$
|
||||
} catch (IOException e) {
|
||||
log.error("Exception initialize renderer", e); //$NON-NLS-1$
|
||||
} catch (SAXException e) {
|
||||
log.error("Exception initialize renderer", e); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultRender;
|
||||
}
|
||||
|
||||
public BaseOsmandRender carRender() {
|
||||
BaseOsmandRender renderer = getRenderer(CAR_RENDER);
|
||||
if(renderer == null){
|
||||
return defaultRender();
|
||||
}
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public BaseOsmandRender bicycleRender() {
|
||||
BaseOsmandRender renderer = getRenderer(BICYCLE_RENDER);
|
||||
if(renderer == null){
|
||||
return defaultRender();
|
||||
}
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public BaseOsmandRender pedestrianRender() {
|
||||
BaseOsmandRender renderer = getRenderer(PEDESTRIAN_RENDER);
|
||||
if(renderer == null){
|
||||
return defaultRender();
|
||||
}
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public BaseOsmandRender getRenderer(String name){
|
||||
public RenderingRulesStorage getRenderer(String name){
|
||||
if(renderers.containsKey(name)){
|
||||
return renderers.get(name);
|
||||
}
|
||||
|
@ -103,7 +57,7 @@ public class RendererRegistry {
|
|||
return externalRenderers.containsKey(name) || internalRenderers.containsKey(name);
|
||||
}
|
||||
|
||||
private BaseOsmandRender getRenderer(String name, Set<String> loadedRenderers) {
|
||||
private RenderingRulesStorage getRenderer(String name, Set<String> loadedRenderers) {
|
||||
try {
|
||||
return loadRenderer(name);
|
||||
} catch (IOException e) {
|
||||
|
@ -114,36 +68,33 @@ public class RendererRegistry {
|
|||
return null;
|
||||
}
|
||||
|
||||
public BaseOsmandRender loadRenderer(String name) throws IOException, SAXException {
|
||||
public RenderingRulesStorage loadRenderer(String name) throws IOException, SAXException {
|
||||
return loadRenderer(name, new LinkedHashSet<String>());
|
||||
}
|
||||
|
||||
private BaseOsmandRender loadRenderer(String name, Set<String> loadedRenderers) throws IOException, SAXException {
|
||||
private RenderingRulesStorage loadRenderer(String name, Set<String> loadedRenderers) throws IOException, SAXException {
|
||||
InputStream is = null;
|
||||
if(externalRenderers.containsKey(name)){
|
||||
is = new FileInputStream(externalRenderers.get(name));
|
||||
} else if(internalRenderers.containsKey(name)){
|
||||
is = OsmandRenderingRulesParser.class.getResourceAsStream(internalRenderers.get(name));
|
||||
is = RenderingRulesStorage.class.getResourceAsStream(internalRenderers.get(name));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Not found " + name); //$NON-NLS-1$
|
||||
}
|
||||
BaseOsmandRender b = new BaseOsmandRender();
|
||||
b.init(is);
|
||||
RenderingRulesStorage b = new RenderingRulesStorage();
|
||||
b.parseRulesFromXmlInputStream(is);
|
||||
loadedRenderers.add(name);
|
||||
List<BaseOsmandRender> dependencies = new ArrayList<BaseOsmandRender>();
|
||||
for (String s : b.getDepends()) {
|
||||
if (loadedRenderers.contains(s)) {
|
||||
if(!Algoritms.isEmpty(b.getDepends())){
|
||||
if (loadedRenderers.contains(b.getDepends())) {
|
||||
log.warn("Circular dependencies found " + name); //$NON-NLS-1$
|
||||
} else {
|
||||
BaseOsmandRender dep = getRenderer(s, loadedRenderers);
|
||||
RenderingRulesStorage dep = getRenderer(b.getDepends(), loadedRenderers);
|
||||
if (dep == null) {
|
||||
log.warn("Dependent renderer not found : " + name); //$NON-NLS-1$
|
||||
} else{
|
||||
dependencies.add(dep);
|
||||
}
|
||||
// TODO set dependent renders
|
||||
}
|
||||
}
|
||||
b.setDependRenderers(dependencies);
|
||||
renderers.put(name, b);
|
||||
return b;
|
||||
}
|
||||
|
@ -161,14 +112,14 @@ public class RendererRegistry {
|
|||
return names;
|
||||
}
|
||||
|
||||
public BaseOsmandRender getCurrentSelectedRenderer() {
|
||||
public RenderingRulesStorage getCurrentSelectedRenderer() {
|
||||
if(currentSelectedRender == null){
|
||||
return defaultRender();
|
||||
}
|
||||
return currentSelectedRender;
|
||||
}
|
||||
|
||||
public void setCurrentSelectedRender(BaseOsmandRender currentSelectedRender) {
|
||||
public void setCurrentSelectedRender(RenderingRulesStorage currentSelectedRender) {
|
||||
this.currentSelectedRender = currentSelectedRender;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue