private static PresenceAbsenceTermBase<?> defaultStatus = PresenceTerm.PRESENT();\r
\r
private static HashMap<Class<? extends SpecimenOrObservationBase>, Color> defaultSpecimenOrObservationTypeColors;\r
+ private static HashMap<PresenceAbsenceTermBase<?>, Color> defaultPresenceAbsenceTermBaseColors;\r
\r
- private static final String MS_SEPARATOR = ",";\r
+ private static final String SUBENTRY_DELIMITER = ",";\r
+ private static final String ENTRY_DELIMITER = ";";\r
+ static final String ID_FROM_VALUES_SEPARATOR = ":";\r
+ static final String VALUE_LIST_ENTRY_SEPARATOR = "|";\r
+ static final String VALUE_SUPER_LIST_ENTRY_SEPARATOR = "||";\r
\r
static {\r
defaultSpecimenOrObservationTypeColors = new HashMap<Class<? extends SpecimenOrObservationBase>, Color>();\r
defaultSpecimenOrObservationTypeColors.put(LivingBeing.class, Color.GREEN);\r
defaultSpecimenOrObservationTypeColors.put(Observation.class, Color.ORANGE);\r
defaultSpecimenOrObservationTypeColors.put(Specimen.class, Color.GRAY);\r
- \r
}\r
-\r
\r
-// @Transient\r
-// public static String getOccurrenceServiceRequestParameterString()\r
-// \r
+ static {\r
+ defaultPresenceAbsenceTermBaseColors = new HashMap<PresenceAbsenceTermBase<?>, Color>();\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceTerm.PRESENT(), Color.decode("0x4daf4a"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceTerm.NATIVE(), Color.decode("0x4daf4a"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceTerm.NATIVE_DOUBTFULLY_NATIVE(), Color.decode("0x377eb8"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceTerm.CULTIVATED(), Color.decode("0x984ea3"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceTerm.INTRODUCED(), Color.decode("0xff7f00"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceTerm.INTRODUCED_ADVENTITIOUS(), Color.decode("0xffff33"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceTerm.INTRODUCED_CULTIVATED(), Color.decode("0xa65628"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceTerm.INTRODUCED_NATURALIZED(), Color.decode("0xf781bf")); \r
+ }\r
+ \r
+\r
\r
//preliminary implementation for TDWG areas\r
/**\r
- * Returns the parameter String for the EDIT geo webservice to create a dsitribution map.\r
- * @param distributions A set of distributions that should be shown on the map\r
- * @param presenceAbsenceTermColors A map that defines the colors of PresenceAbsenceTerms. \r
- * The PresenceAbsenceTerms are defined by their uuid. If a PresenceAbsenceTerm is not included in\r
- * this map, it's default color is taken instead. If the map == null all terms are colored by their default color. \r
- * @param width The maps width\r
- * @param height The maps height\r
- * @param bbox The maps bounding box (e.g. "-180,-90,180,90" for the whole world)\r
- * @param layer The layer that is responsible for background borders and colors. Use the name for the layer.\r
- * If null 'earth' is taken as default. \r
- * @return the parameter string or an empty string if the <code>distributions</code> set was null or empty.\r
+ * Returns the parameter String for the EDIT geo webservice to create a\r
+ * dsitribution map.\r
+ * \r
+ * @param distributions\r
+ * A set of distributions that should be shown on the map\r
+ * @param presenceAbsenceTermColors\r
+ * A map that defines the colors of PresenceAbsenceTerms. The\r
+ * PresenceAbsenceTerms are defined by their uuid. If a\r
+ * PresenceAbsenceTerm is not included in this map, it's default\r
+ * color is taken instead. If the map == null all terms are\r
+ * colored by their default color.\r
+ * @param width\r
+ * The maps width\r
+ * @param height\r
+ * The maps height\r
+ * @param bbox\r
+ * The maps bounding box (e.g. "-180,-90,180,90" for the whole\r
+ * world)\r
+ * @param layer\r
+ * The layer that is responsible for background borders and\r
+ * colors. Use the name for the layer. If null 'earth' is taken\r
+ * as default.\r
+ * @return the parameter string or an empty string if the\r
+ * <code>distributions</code> set was null or empty.\r
*/\r
@Transient\r
public static String getDistributionServiceRequestParameterString(\r
String backLayer,\r
List<Language> languages){\r
\r
- String result = "";\r
- String layer = ""; \r
- String areaData = "";\r
- String areaStyle = "";\r
- String areaTitle = "";\r
- String adLayerSeparator = ":";\r
- String styleInAreaDataSeparator = "|";\r
- double borderWidth = 0.1;\r
+\r
+ /**\r
+ * generateMultipleAreaDataParameters switches between the two possible styles:\r
+ * 1. ad=layername1:area-data||layername2:area-data\r
+ * 2. ad=layername1:area-data&ad=layername2:area-data\r
+ */\r
+ boolean generateMultipleAreaDataParameters = false;\r
+\r
+ List<String> perLayerAreaData = new ArrayList<String>();\r
+ List<String> areaStyles = new ArrayList<String>();\r
+ List<String> legendLabels = new ArrayList<String>();\r
+\r
+ \r
+ String borderWidth = "0.1";\r
+ String borderColorRgb = "";\r
+ String borderDashingPattern = "";\r
\r
\r
if(distributions == null || distributions.size() == 0){\r
return "";\r
}\r
- if (presenceAbsenceTermColors == null) {\r
- //presenceAbsenceTermColors = new HashMap<PresenceAbsenceTermBase<?>, Color>();\r
- presenceAbsenceTermColors = makeDefaultColorMap();\r
- }\r
-\r
- //List<String> layerStrings = new ArrayList<String>(); \r
Map<String, Map<Integer, Set<Distribution>>> layerMap = new HashMap<String, Map<Integer, Set<Distribution>>>(); \r
List<PresenceAbsenceTermBase<?>> statusList = new ArrayList<PresenceAbsenceTermBase<?>>();\r
+ groupStylesAndLayers(distributions, layerMap, statusList);\r
+ \r
+ presenceAbsenceTermColors = mergeMaps(defaultPresenceAbsenceTermBaseColors, presenceAbsenceTermColors);\r
+\r
+ Map<String, String> parameters = new HashMap<String, String>();\r
\r
- //bbox, width, hight\r
- if (bbox == null){\r
- // FIXME uncommented this as it can not be desirable to have default values in this method\r
- // we need a parameterString that consists of essential parameters only \r
- // defaults should be implemented in the geoservice itself.\r
- //bbox ="bbox=-180,-90,180,90"; //earth is default\r
- }else{\r
- bbox = "bbox=" + bbox;\r
+ //bbox\r
+ if (bbox != null){\r
+ parameters.put("bbox", bbox);\r
}\r
- String ms = mapSizeParameter(width, height);\r
- \r
- //iterate through distributions and group styles and layers\r
- //and collect necessary information\r
- for (Distribution distribution:distributions){\r
- //collect status\r
- PresenceAbsenceTermBase<?> status = distribution.getStatus();\r
- if(status == null){\r
- status = defaultStatus;\r
- }\r
- if (! statusList.contains(status)){\r
- statusList.add(status);\r
- }\r
- //group by layers and styles\r
- NamedArea area = distribution.getArea();\r
- if (area != null){\r
- String geoLayerString = getGeoServiceLayer(area);\r
- Map<Integer, Set<Distribution>> styleMap = layerMap.get(geoLayerString);\r
- if (styleMap == null){\r
- styleMap = new HashMap<Integer, Set<Distribution>>();\r
- layerMap.put(geoLayerString, styleMap);\r
- }\r
- addDistributionToMap(distribution, styleMap, statusList);\r
- }\r
+ // map size\r
+ String ms = compileMapSizeParameterValue(width, height);\r
+ if(ms != null){\r
+ parameters.put("ms", ms);\r
}\r
- \r
//layer\r
if (StringUtils.isBlank(backLayer)){\r
backLayer = "earth"; \r
}\r
- layer = "l="+backLayer;\r
-// for (String layerString : layerMap.keySet()){\r
-// layer += "," + layerString;\r
-// }\r
- //layer = "l=" + layer.substring(1); //remove first |\r
- \r
+ parameters.put("l", backLayer);\r
\r
//style\r
- areaStyle = "";\r
int i = 0;\r
for (PresenceAbsenceTermBase<?> status: statusList){\r
\r
- char style = getStyleAbbrev(i);\r
+ char styleId = getStyleAbbrev(i);\r
\r
//getting the area title\r
if (languages == null){\r
//statusLabel.replace('introduced: ', '');\r
statusLabel = statusLabel.replace("introduced: ", "introduced, ");\r
statusLabel = statusLabel.replace("native: ", "native, ");\r
- areaTitle += "|" + style + ":" + statusLabel;\r
\r
//getting the area color\r
Color statusColor = presenceAbsenceTermColors.get(status);\r
- String rgb;\r
+ String fillColorRgb;\r
if (statusColor != null){\r
- rgb = Integer.toHexString(statusColor.getRGB()).substring(2);\r
+ fillColorRgb = Integer.toHexString(statusColor.getRGB()).substring(2);\r
}else{\r
if(status != null){\r
- rgb = status.getDefaultColor(); //TODO\r
+ fillColorRgb = status.getDefaultColor(); //TODO\r
} else {\r
- rgb = defaultStatus.getDefaultColor();\r
+ fillColorRgb = defaultStatus.getDefaultColor();\r
}\r
}\r
- areaStyle += "|" + style + ":" + rgb;\r
-\r
- if (borderWidth >0){\r
- areaStyle += ",," + borderWidth;\r
- }\r
+ String styleValues = StringUtils.join(new String[]{fillColorRgb, borderColorRgb, borderWidth, borderDashingPattern}, ','); \r
\r
+ areaStyles.add(styleId + ID_FROM_VALUES_SEPARATOR + styleValues);\r
+ legendLabels.add(styleId + ID_FROM_VALUES_SEPARATOR + encode(statusLabel));\r
i++; \r
}\r
\r
- if(areaStyle.length() > 0){\r
- areaStyle = "as=" + areaStyle.substring(1); //remove first |\r
+ if(areaStyles.size() > 0){\r
+ parameters.put("as", StringUtils.join(areaStyles.iterator(), VALUE_LIST_ENTRY_SEPARATOR));\r
}\r
- if(areaTitle.length() > 0){\r
- areaTitle = "title=" + encode(areaTitle.substring(1)); //remove first |\r
+ if(legendLabels.size() > 0){\r
+ parameters.put("title", StringUtils.join(legendLabels.iterator(), VALUE_LIST_ENTRY_SEPARATOR));\r
}\r
\r
- boolean separateLevels = false; //FIXME as parameter\r
- //areaData\r
- areaData = "";\r
- boolean isFirstLayer = true;\r
- Map<String, String> resultMap = new HashMap<String, String>();\r
- \r
+ // area data\r
+ List<String> stylesPerLayer;\r
+ List<String> areasPerStyle;\r
for (String layerString : layerMap.keySet()){\r
- areaData += (isFirstLayer? "" : "||") + layerString + adLayerSeparator;\r
+ // each layer\r
+ stylesPerLayer = new ArrayList<String>();\r
Map<Integer, Set<Distribution>> styleMap = layerMap.get(layerString);\r
- boolean isFirstStyle = true;\r
for (int style: styleMap.keySet()){\r
+ // stylesPerLayer\r
char styleChar = getStyleAbbrev(style);\r
- areaData += (isFirstStyle? "" : styleInAreaDataSeparator) + styleChar + ":";\r
Set<Distribution> distributionSet = styleMap.get(style);\r
- boolean isFirstDistribution = true;\r
+ areasPerStyle = new ArrayList<String>();\r
for (Distribution distribution: distributionSet){\r
- String areaAbbrev = getAreaAbbrev(distribution);\r
- areaData += (isFirstDistribution ? "" : ",") + areaAbbrev;\r
- isFirstDistribution = false;\r
+ // areasPerStyle\r
+ areasPerStyle.add(getAreaAbbrev(distribution));\r
}\r
- isFirstStyle = false;\r
- }\r
- isFirstLayer = separateLevels;\r
- if(separateLevels){\r
- //result per level\r
- result = CdmUtils.concat("&", new String[] {layer, "ad=" + areaData.substring(0), areaStyle, areaTitle, bbox, ms});\r
- resultMap.put(layerString, result);\r
+ stylesPerLayer.add(styleChar + ID_FROM_VALUES_SEPARATOR + StringUtils.join(areasPerStyle.iterator(), SUBENTRY_DELIMITER));\r
}\r
+ perLayerAreaData.add(encode(layerString) + ID_FROM_VALUES_SEPARATOR + StringUtils.join(stylesPerLayer.iterator(), VALUE_LIST_ENTRY_SEPARATOR));\r
}\r
\r
- areaData = "ad=" + areaData.substring(0); //remove first |\r
- \r
- //result\r
- result = CdmUtils.concat("&", new String[] {layer, areaData, areaStyle, areaTitle, bbox, ms});\r
- if (logger.isDebugEnabled()){logger.debug("getEditGeoServiceUrlParameterString end");}\r
+ if(generateMultipleAreaDataParameters){\r
+ // not generically possible since parameters can not contain duplicate keys with value "ad"\r
+ } else {\r
+ parameters.put("ad", StringUtils.join(perLayerAreaData.iterator(), VALUE_SUPER_LIST_ENTRY_SEPARATOR));\r
+ }\r
+\r
+ String queryString = makeQueryString(parameters);\r
+ logger.debug("getDistributionServiceRequestParameterString(): " + queryString);\r
\r
- return result;\r
+ return queryString;\r
}\r
\r
- private static String mapSizeParameter(int width, int height) {\r
+ private static void groupStylesAndLayers(Set<Distribution> distributions,\r
+ Map<String, Map<Integer, Set<Distribution>>> layerMap,\r
+ List<PresenceAbsenceTermBase<?>> statusList) {\r
+ //iterate through distributions and group styles and layers\r
+ //and collect necessary information\r
+ for (Distribution distribution:distributions){\r
+ //collect status\r
+ PresenceAbsenceTermBase<?> status = distribution.getStatus();\r
+ if(status == null){\r
+ status = defaultStatus;\r
+ }\r
+ if (! statusList.contains(status)){\r
+ statusList.add(status);\r
+ }\r
+ //group by layers and styles\r
+ NamedArea area = distribution.getArea();\r
+ if (area != null){\r
+ String geoLayerString = getWMSLayerName(area);\r
+ if(geoLayerString != null){\r
+ Map<Integer, Set<Distribution>> styleMap = layerMap.get(geoLayerString);\r
+ if (styleMap == null){\r
+ styleMap = new HashMap<Integer, Set<Distribution>>();\r
+ layerMap.put(geoLayerString, styleMap);\r
+ }\r
+ addDistributionToMap(distribution, styleMap, statusList);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private static String compileMapSizeParameterValue(int width, int height) {\r
\r
String widthStr = "";\r
String heightStr = "";\r
widthStr = "" + width;\r
}\r
if (height > 0) {\r
- heightStr = MS_SEPARATOR + height;\r
+ heightStr = SUBENTRY_DELIMITER + height;\r
}\r
- String ms = "ms=" + widthStr + heightStr;\r
- if (ms.equals("ms=")) {\r
+ String ms = widthStr + heightStr;\r
+ if(ms.length() == 0){\r
ms = null;\r
}\r
return ms;\r
if(queryString.length() > 0){\r
queryString.append('&');\r
}\r
- if(key.equals("od") || key.equals("os")){\r
+ if(key.equals("od") || key.equals("os") || key.equals("ms") || key.equals("ad") || key.equals("as") || key.equals("title") || key.equals("bbox")){\r
queryString.append(key).append('=').append(parameters.get(key)); \r
} else {\r
queryString.append(key).append('=').append(encode(parameters.get(key)));\r
return queryString.toString();\r
}\r
\r
- private static Map<PresenceAbsenceTermBase<?>,Color> makeDefaultColorMap(){\r
- Map<PresenceAbsenceTermBase<?>,Color> result = new HashMap<PresenceAbsenceTermBase<?>, Color>();\r
- try {\r
- result.put(PresenceTerm.PRESENT(), Color.decode("0x4daf4a"));\r
- result.put(PresenceTerm.NATIVE(), Color.decode("0x4daf4a"));\r
- result.put(PresenceTerm.NATIVE_DOUBTFULLY_NATIVE(), Color.decode("0x377eb8"));\r
- result.put(PresenceTerm.CULTIVATED(), Color.decode("0x984ea3"));\r
- result.put(PresenceTerm.INTRODUCED(), Color.decode("0xff7f00"));\r
- result.put(PresenceTerm.INTRODUCED_ADVENTITIOUS(), Color.decode("0xffff33"));\r
- result.put(PresenceTerm.INTRODUCED_CULTIVATED(), Color.decode("0xa65628"));\r
- result.put(PresenceTerm.INTRODUCED_NATURALIZED(), Color.decode("0xf781bf"));\r
- } catch (NumberFormatException nfe) {\r
- logger.error(nfe);\r
- }\r
- return result;\r
- }\r
- \r
- \r
-\r
private static String getAreaAbbrev(Distribution distribution){\r
NamedArea area = distribution.getArea();\r
Representation representation = area.getRepresentation(Language.DEFAULT());\r
//Preliminary as long as user defined areas are not fully implemented \r
public static final UUID uuidCyprusDivisionsVocabulary = UUID.fromString("2119f610-1f93-4d87-af28-40aeefaca100");\r
\r
- private static String getGeoServiceLayer(NamedArea area){\r
+ private static String getWMSLayerName(NamedArea area){\r
TermVocabulary<NamedArea> voc = area.getVocabulary();\r
//TDWG areas\r
if (voc.getUuid().equals(TdwgArea.uuidTdwgAreaVocabulary)){\r
}\r
}\r
//unrecognized tdwg area\r
- return "unknown";\r
+ return null;\r
\r
}\r
//hardcoded for cyprus (as long as user defined areas are not fully implemented). Remove afterwards.\r
if (voc.getUuid().equals(uuidCyprusDivisionsVocabulary)){\r
return "cyprusdivs:bdcode";\r
}\r
- return "unknown";\r
+ return null;\r
}\r
\r
\r
parameters.put("bbox", bbox);\r
}\r
if(width != null || height != null){\r
- parameters.put("ms", mapSizeParameter(width, height));\r
+ parameters.put("ms", compileMapSizeParameterValue(width, height));\r
}\r
\r
Map<String, String> styleAndData = new HashMap<String, String>();\r