package eu.etaxonomy.cdm.ext.geo;\r
\r
import java.awt.Color;\r
+import java.io.IOException;\r
import java.io.UnsupportedEncodingException;\r
import java.net.URLEncoder;\r
import java.util.ArrayList;\r
\r
import javax.persistence.Transient;\r
\r
+import org.apache.commons.collections.CollectionUtils;\r
+import org.apache.commons.collections.Transformer;\r
import org.apache.commons.lang.StringUtils;\r
import org.apache.log4j.Logger;\r
-\r
+import org.codehaus.jackson.JsonParseException;\r
+import org.codehaus.jackson.map.JsonMappingException;\r
+import org.codehaus.jackson.map.ObjectMapper;\r
+import org.codehaus.jackson.map.type.MapType;\r
+import org.codehaus.jackson.map.type.TypeFactory;\r
+\r
+import eu.etaxonomy.cdm.api.service.ITermService;\r
+import eu.etaxonomy.cdm.api.service.dto.CondensedDistribution;\r
import eu.etaxonomy.cdm.api.utility.DescriptionUtility;\r
import eu.etaxonomy.cdm.common.CdmUtils;\r
-import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;\r
-import eu.etaxonomy.cdm.model.common.DefinedTermBase;\r
import eu.etaxonomy.cdm.model.common.Language;\r
import eu.etaxonomy.cdm.model.common.Representation;\r
import eu.etaxonomy.cdm.model.common.TermVocabulary;\r
import eu.etaxonomy.cdm.model.description.Distribution;\r
-import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;\r
-import eu.etaxonomy.cdm.model.description.PresenceTerm;\r
+import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;\r
+import eu.etaxonomy.cdm.model.location.Country;\r
import eu.etaxonomy.cdm.model.location.NamedArea;\r
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;\r
import eu.etaxonomy.cdm.model.location.Point;\r
public class EditGeoServiceUtilities {\r
private static final Logger logger = Logger.getLogger(EditGeoServiceUtilities.class);\r
\r
- private static PresenceAbsenceTermBase<?> defaultStatus = PresenceTerm.PRESENT();\r
+ private static final int INT_MAX_LENGTH = String.valueOf(Integer.MAX_VALUE).length();\r
+\r
+ private static PresenceAbsenceTerm defaultStatus = PresenceAbsenceTerm.PRESENT();\r
\r
private static IDefinedTermDao termDao;\r
\r
EditGeoServiceUtilities.termDao= termDao;\r
}\r
\r
+\r
private static HashMap<SpecimenOrObservationType, Color> defaultSpecimenOrObservationTypeColors = null;\r
\r
private static HashMap<SpecimenOrObservationType, Color> getDefaultSpecimenOrObservationTypeColors() {\r
}\r
\r
\r
- private static HashMap<PresenceAbsenceTermBase<?>, Color> defaultPresenceAbsenceTermBaseColors = null;\r
+ private static HashMap<PresenceAbsenceTerm, Color> defaultPresenceAbsenceTermBaseColors = null;\r
\r
- private static HashMap<PresenceAbsenceTermBase<?>, Color> getDefaultPresenceAbsenceTermBaseColors() {\r
+ private static HashMap<PresenceAbsenceTerm, Color> getDefaultPresenceAbsenceTermBaseColors() {\r
if(defaultPresenceAbsenceTermBaseColors == null){\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
+ defaultPresenceAbsenceTermBaseColors = new HashMap<PresenceAbsenceTerm, Color>();\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceAbsenceTerm.PRESENT(), Color.decode("0x4daf4a"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceAbsenceTerm.NATIVE(), Color.decode("0x4daf4a"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceAbsenceTerm.NATIVE_DOUBTFULLY_NATIVE(), Color.decode("0x377eb8"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceAbsenceTerm.CULTIVATED(), Color.decode("0x984ea3"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceAbsenceTerm.INTRODUCED(), Color.decode("0xff7f00"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceAbsenceTerm.INTRODUCED_ADVENTITIOUS(), Color.decode("0xffff33"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceAbsenceTerm.INTRODUCED_CULTIVATED(), Color.decode("0xa65628"));\r
+ defaultPresenceAbsenceTermBaseColors.put(PresenceAbsenceTerm.INTRODUCED_NATURALIZED(), Color.decode("0xf781bf"));\r
\r
/*\r
* and now something very hacky ...\r
* ONLY-A-TEST is set by the Test class EditGeoServiceTest\r
*\r
- * TODO remove according line from\r
- * EditGeoServiceTest.setUp() when the hardcoded colors for flora of\r
- * cyprus are no further needed !!\r
+ * FIXME remove according line from\r
+ * EditGeoServiceTest.setUp() since the hardcoded colors for flora of\r
+ * cyprus should no longer be needed : #4268 (allow defining custom presence and absence term colors for EditGeoServiceUtilities)\r
*/\r
String onlyTest = System.getProperty("ONLY-A-TEST"); //\r
if(onlyTest != null && onlyTest.equals("TRUE")){\r
\r
UUID reportedInErrorUuid = UUID.fromString("38604788-cf05-4607-b155-86db456f7680");\r
\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(indigenousUuid), Color.decode("0x339966"));\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(indigenousQUuid), Color.decode("0x339966"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(indigenousUuid), Color.decode("0x339966"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(indigenousQUuid), Color.decode("0x339966"));\r
\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(cultivatedQUuid), Color.decode("0xbdb76b"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(cultivatedQUuid), Color.decode("0xbdb76b"));\r
\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(casualUuid), Color.decode("0xffff00"));\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(casualQUuid), Color.decode("0xffff00"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(casualUuid), Color.decode("0xffff00"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(casualQUuid), Color.decode("0xffff00"));\r
\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(naturalizedNonInvasiveUuid), Color.decode("0xff9900"));\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(naturalizedNonInvasiveQUuid), Color.decode("0xff9900"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(naturalizedNonInvasiveUuid), Color.decode("0xff9900"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(naturalizedNonInvasiveQUuid), Color.decode("0xff9900"));\r
\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(naturalizedInvasiveUuid), Color.decode("0xff0000"));\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(naturalizedInvasiveQUuid), Color.decode("0xff0000"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(naturalizedInvasiveUuid), Color.decode("0xff0000"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(naturalizedInvasiveQUuid), Color.decode("0xff0000"));\r
\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(questionablelUuid), Color.decode("0x00ccff"));\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(questionableQUuid), Color.decode("0x00ccff"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(questionablelUuid), Color.decode("0x00ccff"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(questionableQUuid), Color.decode("0x00ccff"));\r
\r
- defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTermBase<?>) termDao.load(reportedInErrorUuid), Color.decode("0xcccccc"));\r
+ defaultPresenceAbsenceTermBaseColors.put((PresenceAbsenceTerm) termDao.load(reportedInErrorUuid), Color.decode("0xcccccc"));\r
\r
}\r
return defaultPresenceAbsenceTermBaseColors;\r
static final String VALUE_SUPER_LIST_ENTRY_SEPARATOR = "||";\r
\r
\r
-\r
- //preliminary implementation for TDWG areas\r
/**\r
* Returns the parameter String for the EDIT geo webservice to create a\r
- * dsitribution map.\r
+ * distribution map.\r
*\r
* @param distributions\r
* A set of distributions that should be shown on the map\r
+ * The {@link DescriptionUtility} class provides a method for\r
+ * filtering a set of Distributions :\r
+ *\r
+ * {@code\r
+ * Collection<Distribution> filteredDistributions =\r
+ * DescriptionUtility.filterDistributions(distributions,\r
+ * subAreaPreference, statusOrderPreference, hideMarkedAreas);\r
+ * }\r
+ * @param mapping\r
+ * Data regarding the mapping of NamedAreas to shape file\r
+ * attribute tables\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 projectToLayer\r
* name of a layer which is representing a specific\r
* {@link NamedAreaLevel} Supply this parameter if you to project\r
* all other distribution area levels to this layer.\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
+ * @param languages\r
+ *\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
- Set<Distribution> distributions,\r
+ Collection<Distribution> filteredDistributions,\r
IGeoServiceAreaMapping mapping,\r
- Map<PresenceAbsenceTermBase<?>,Color> presenceAbsenceTermColors,\r
- int width,\r
- int height,\r
- String bbox,\r
- String baseLayerName,\r
+ Map<PresenceAbsenceTerm,Color> presenceAbsenceTermColors,\r
String projectToLayer,\r
List<Language> languages){\r
\r
\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
- /**\r
+ /*\r
* doNotReuseStyles is a workaround for a problem in the EDIT MapService,\r
* see https://dev.e-taxonomy.eu/trac/ticket/2707#comment:24\r
+ *\r
+ * a.kohlbecker 2014-07-02 :This bug in the map service has been\r
+ * fixed now so reusing styles is now possible setting this flag to false.\r
*/\r
- boolean doNotReuseStyles = true;\r
+ boolean doNotReuseStyles = false;\r
\r
List<String> perLayerAreaData = new ArrayList<String>();\r
- Map<Integer, String> areaStyles = new HashMap<Integer, String>();\r
- List<String> legendLabels = new ArrayList<String>();\r
-\r
+ Map<Integer, String> areaStyles = new HashMap<Integer, String>();\r
+ List<String> legendSortList = new ArrayList<String>();\r
\r
String borderWidth = "0.1";\r
String borderColorRgb = "";\r
\r
\r
//handle empty set\r
- if(distributions == null || distributions.size() == 0){\r
+ if(filteredDistributions == null || filteredDistributions.size() == 0){\r
return "";\r
}\r
\r
- Collection<Distribution> filteredDistributions = DescriptionUtility.filterDistributions(distributions);\r
+ presenceAbsenceTermColors = mergeMaps(getDefaultPresenceAbsenceTermBaseColors(), presenceAbsenceTermColors);\r
\r
Map<String, Map<Integer, Set<Distribution>>> layerMap = new HashMap<String, Map<Integer, Set<Distribution>>>();\r
- List<PresenceAbsenceTermBase<?>> statusList = new ArrayList<PresenceAbsenceTermBase<?>>();\r
+ List<PresenceAbsenceTerm> statusList = new ArrayList<PresenceAbsenceTerm>();\r
\r
- // TODO this step seems to be taking too much time\r
groupStylesAndLayers(filteredDistributions, layerMap, statusList, mapping);\r
\r
- presenceAbsenceTermColors = mergeMaps(getDefaultPresenceAbsenceTermBaseColors(), presenceAbsenceTermColors);\r
-\r
Map<String, String> parameters = new HashMap<String, String>();\r
\r
- //bbox\r
- if (bbox != null){\r
- parameters.put("bbox", bbox);\r
- }\r
- // map size\r
- String ms = compileMapSizeParameterValue(width, height);\r
- if(ms != null){\r
- parameters.put("ms", ms);\r
- }\r
- //layer\r
-// if (StringUtils.isBlank(baseLayerName)){\r
-// baseLayerName = "earth";\r
-// }\r
- if (!StringUtils.isBlank(baseLayerName)){\r
- parameters.put("l", baseLayerName);\r
- }\r
-\r
//style\r
int styleCounter = 0;\r
- for (PresenceAbsenceTermBase<?> status: statusList){\r
+ for (PresenceAbsenceTerm status: statusList){\r
\r
char styleCode = getStyleAbbrev(styleCounter);\r
\r
if (languages.size() == 0){\r
languages.add(Language.DEFAULT());\r
}\r
- Representation representation = status.getPreferredRepresentation(languages);\r
- String statusLabel = representation.getLabel();\r
- //statusLabel.replace('introduced: ', '');\r
- statusLabel = statusLabel.replace("introduced: ", "introduced, ");\r
- statusLabel = statusLabel.replace("native: ", "native, ");\r
+ Representation statusRepresentation = status.getPreferredRepresentation(languages);\r
\r
//getting the area color\r
Color statusColor = presenceAbsenceTermColors.get(status);\r
String styleValues = StringUtils.join(new String[]{fillColorRgb, borderColorRgb, borderWidth, borderDashingPattern}, ',');\r
\r
areaStyles.put(styleCounter, styleValues);\r
- legendLabels.add(styleCode + ID_FROM_VALUES_SEPARATOR + encode(statusLabel));\r
+\r
+ String legendEntry = styleCode + ID_FROM_VALUES_SEPARATOR + encode(statusRepresentation.getLabel());\r
+ legendSortList.add(StringUtils.leftPad(String.valueOf(status.getOrderIndex()), INT_MAX_LENGTH, '0') + legendEntry );\r
styleCounter++;\r
}\r
\r
List<String> styledAreasPerLayer;\r
List<String> areasPerStyle;\r
/**\r
+ * Map<Integer, Integer> styleUsage\r
+ *\r
* Used to avoid reusing styles in multiple layers\r
*\r
* key: the style id\r
* value: the count of how often the style has been used for different layers, starts with 0 for first time use\r
*/\r
Map<Integer, Integer> styleUsage = new HashMap<Integer, Integer>();\r
+\r
char styleChar;\r
for (String layerString : layerMap.keySet()){\r
// each layer\r
if(styleIncrement > 0){\r
// style code has been used before!\r
styleChar = getStyleAbbrev(style + styleIncrement + styleCounter);\r
+ //for debugging sometimes failing test #3831\r
+ logger.warn("style: " + style + ", styleIncrement: " + styleIncrement + ", styleCounter: " + styleCounter);\r
areaStyles.put(style + styleIncrement + styleCounter, areaStyles.get(style));\r
} else {\r
styleChar = getStyleAbbrev(style);\r
if(areaStyles.size() > 0){\r
ArrayList<Integer> styleIds = new ArrayList<Integer>(areaStyles.size());\r
styleIds.addAll(areaStyles.keySet());\r
- Collections.sort(styleIds);\r
+ Collections.sort(styleIds); // why is it necessary to sort here?\r
StringBuilder db = new StringBuilder();\r
for(Integer sid : styleIds){\r
if(db.length() > 0){\r
}\r
parameters.put("as", db.toString());\r
}\r
- if(legendLabels.size() > 0){\r
- parameters.put("title", StringUtils.join(legendLabels.iterator(), VALUE_LIST_ENTRY_SEPARATOR));\r
- }\r
+ if(legendSortList.size() > 0){\r
+ // sort the label entries after the status terms\r
+ Collections.sort(legendSortList);\r
+ // since the status terms are have an inverse natural order\r
+ // (as all other ordered term, see OrderedTermBase.performCompareTo(T orderedTerm, boolean skipVocabularyCheck)\r
+ // the sorted list must be reverted\r
+// Collections.reverse(legendSortList);\r
+ // remove the prepended order index (like 000000000000001 ) from the legend entries\r
+ @SuppressWarnings("unchecked")\r
+ Collection<String> legendEntries = CollectionUtils.collect(legendSortList, new Transformer()\r
+ {\r
+ @Override\r
+ public String transform(Object o)\r
+ {\r
+ String s = ((String) o);\r
+ return s.substring(INT_MAX_LENGTH, s.length());\r
+ }\r
+ });\r
\r
+ parameters.put("title", StringUtils.join(legendEntries.iterator(), VALUE_LIST_ENTRY_SEPARATOR));\r
+ }\r
\r
if(generateMultipleAreaDataParameters){\r
// not generically possible since parameters can not contain duplicate keys with value "ad"\r
*/\r
private static void groupStylesAndLayers(Collection<Distribution> distributions,\r
Map<String, Map<Integer,Set<Distribution>>> layerMap,\r
- List<PresenceAbsenceTermBase<?>> statusList,\r
+ List<PresenceAbsenceTerm> statusList,\r
IGeoServiceAreaMapping mapping) {\r
\r
\r
//and collect necessary information\r
for (Distribution distribution : distributions){\r
//collect status\r
- PresenceAbsenceTermBase<?> status = distribution.getStatus();\r
+ PresenceAbsenceTerm status = distribution.getStatus();\r
if(status == null){\r
status = defaultStatus;\r
}\r
}\r
\r
/**\r
+ * Adds the areas to the layer map. Areas which do not have layer information\r
+ * mapped to them are ignored.\r
+ * <p>\r
* A layer map holds the following information:\r
*\r
* <ul>\r
*/\r
private static void addAreaToLayerMap(Map<String, Map<Integer,\r
Set<Distribution>>> layerMap,\r
- List<PresenceAbsenceTermBase<?>> statusList,\r
+ List<PresenceAbsenceTerm> statusList,\r
Distribution distribution,\r
NamedArea area,\r
IGeoServiceAreaMapping mapping) {\r
\r
if (area != null){\r
- String geoLayerString = getWMSLayerName(area, mapping);\r
-\r
- if(geoLayerString == null){\r
-\r
- // if no layer is mapped this area descend into sub areas in order to project\r
- // the distribution to those\r
- /**\r
- * FIXME ClassCaseException!!!\r
- * getIncludes(): Hibernate returns this as a collection of CGLibProxy$$DefinedTermBase objects\r
- * which can't be cast to instances of T - can we explicitly initialize these terms using\r
- * Hibernate.initialize(), does this imply a distinct load, and find methods in the dao?\r
- */\r
- for(DefinedTermBase<?> dtb : area.getIncludes()){\r
- NamedArea subArea = HibernateProxyHelper.deproxy(dtb, NamedArea.class);\r
- addAreaToLayerMap(layerMap, statusList, distribution, subArea, mapping);\r
- }\r
+ String geoLayerName = getWMSLayerName(area, mapping);\r
\r
+ if(geoLayerName == null){\r
+ /* IGNORE areas for which no layer is mapped */\r
} else {\r
-\r
- Map<Integer, Set<Distribution>> styleMap = layerMap.get(geoLayerString);\r
+ Map<Integer, Set<Distribution>> styleMap = layerMap.get(geoLayerName);\r
if (styleMap == null) {\r
styleMap = new HashMap<Integer, Set<Distribution>>();\r
- layerMap.put(geoLayerString, styleMap);\r
+ layerMap.put(geoLayerName, styleMap);\r
}\r
addDistributionToStyleMap(distribution, styleMap, statusList);\r
-\r
}\r
}\r
}\r
\r
\r
- private static String compileMapSizeParameterValue(int width, int height) {\r
-\r
- String widthStr = "";\r
- String heightStr = "";\r
-\r
- if (width > 0) {\r
- widthStr = "" + width;\r
- }\r
- if (height > 0) {\r
- heightStr = SUBENTRY_DELIMITER + height;\r
- }\r
- String ms = widthStr + heightStr;\r
- if(ms.length() == 0){\r
- ms = null;\r
- }\r
- return ms;\r
- }\r
\r
/**\r
* URI encode the given String\r
TermVocabulary<NamedArea> voc = area.getVocabulary();\r
String result = null;\r
\r
- if (voc != null && voc.getUuid().equals(NamedArea.uuidTdwgAreaVocabulary)\r
- || voc.getUuid().equals(uuidCyprusDivisionsVocabulary)) {\r
- // TDWG or Cyprus\r
+ if (voc != null && voc.getUuid().equals(NamedArea.uuidTdwgAreaVocabulary) || voc.getUuid().equals(Country.uuidCountryVocabulary)) {\r
+ // TDWG or Country\r
result = area.getIdInVocabulary();\r
if (area.getLevel() != null && area.getLevel().equals(NamedAreaLevel.TDWG_LEVEL4())) {\r
result = result.replace("-", "");\r
\r
}\r
\r
-\r
-\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 List<String> projectToWMSSubLayer(NamedArea area){\r
\r
List<String> layerNames = new ArrayList<String>();\r
//unrecognized tdwg area\r
\r
}\r
- //TODO hardcoded for cyprus (as long as user defined areas are not fully implemented). Remove afterwards.\r
- if (voc.getUuid().equals(uuidCyprusDivisionsVocabulary)){\r
- matchedLayerName = "cyprusdivs:bdcode";\r
- }\r
+ //TODO countries\r
\r
// check if the matched layer equals the layer to project to\r
// if not: recurse into the sub-level in order to find the specified one.\r
//unrecognized tdwg area\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
+ }else if (voc.getUuid().equals(Country.uuidCountryVocabulary)){\r
+ return "country_earth:gmi_cntry";\r
}\r
\r
GeoServiceArea areas = mapping.valueOf(area);\r
\r
\r
private static void addDistributionToStyleMap(Distribution distribution, Map<Integer, Set<Distribution>> styleMap,\r
- List<PresenceAbsenceTermBase<?>> statusList) {\r
- PresenceAbsenceTermBase<?> status = distribution.getStatus();\r
+ List<PresenceAbsenceTerm> statusList) {\r
+ PresenceAbsenceTerm status = distribution.getStatus();\r
if (status == null) {\r
status = defaultStatus;\r
}\r
* @param fieldUnitPoints\r
* @param derivedUnitPoints\r
* @param specimenOrObservationTypeColors\r
- * @param doReturnImage TODO\r
* @param width\r
* @param height\r
* @param bbox\r
* &od=1%3A44.29481%2C6.82161|44.29252%2C6.822873|44.29247%2C6.82346|44.29279%2C6.823678|44.29269%2C6.82394|44.28482%2C6.887252|44.11469%2C7.287144|44.11468%2C7.289168\r
* &os=1%3Ac%2FFFD700%2F10%2FAporrectodea caliginosa\r
*/\r
- public static String getOccurrenceServiceRequestParameterString(\r
- List<Point> fieldUnitPoints,\r
- List<Point> derivedUnitPoints,\r
- Map<SpecimenOrObservationType, Color> specimenOrObservationTypeColors,\r
- Boolean doReturnImage, Integer width, Integer height, String bbox, String backLayer) {\r
-\r
- specimenOrObservationTypeColors = mergeMaps(getDefaultSpecimenOrObservationTypeColors(), specimenOrObservationTypeColors);\r
-\r
- Map<String, String> parameters = new HashMap<String, String>();\r
- parameters.put("legend", "0");\r
- parameters.put("image", doReturnImage != null && doReturnImage ? "true" : "false");\r
- parameters.put("recalculate", "false"); // TODO add parameter to method\r
- if(bbox != null){\r
- parameters.put("bbox", bbox);\r
- }\r
- if(width != null || height != null){\r
- parameters.put("ms", compileMapSizeParameterValue(width, height));\r
- }\r
+ public static OccurrenceServiceRequestParameterDto getOccurrenceServiceRequestParameterString(\r
+ List<Point> fieldUnitPoints,\r
+ List<Point> derivedUnitPoints,\r
+ Map<SpecimenOrObservationType, Color> specimenOrObservationTypeColors) {\r
+ OccurrenceServiceRequestParameterDto dto = new OccurrenceServiceRequestParameterDto();\r
\r
- Map<String, String> styleAndData = new HashMap<String, String>();\r
\r
- addToStyleAndData(fieldUnitPoints, SpecimenOrObservationType.FieldUnit, specimenOrObservationTypeColors, styleAndData);\r
- addToStyleAndData(derivedUnitPoints, SpecimenOrObservationType.DerivedUnit, specimenOrObservationTypeColors, styleAndData);\r
+ specimenOrObservationTypeColors = mergeMaps(getDefaultSpecimenOrObservationTypeColors(), specimenOrObservationTypeColors);\r
\r
- parameters.put("os", StringUtils.join(styleAndData.keySet().iterator(), "||"));\r
- parameters.put("od", StringUtils.join(styleAndData.values().iterator(), "||"));\r
+ Map<String, String> parameters = new HashMap<String, String>();\r
+ parameters.put("legend", "0");\r
\r
- String queryString = makeQueryString(parameters);\r
+ Map<String, String> styleAndData = new HashMap<String, String>();\r
\r
- logger.info(queryString);\r
+ addToStyleAndData(fieldUnitPoints, SpecimenOrObservationType.FieldUnit, specimenOrObservationTypeColors, styleAndData);\r
+ addToStyleAndData(derivedUnitPoints, SpecimenOrObservationType.DerivedUnit, specimenOrObservationTypeColors, styleAndData);\r
\r
- return queryString;\r
+ parameters.put("os", StringUtils.join(styleAndData.keySet().iterator(), "||"));\r
+ parameters.put("od", StringUtils.join(styleAndData.values().iterator(), "||"));\r
+\r
+ String queryString = makeQueryString(parameters);\r
+\r
+ dto.setFieldUnitPoints(fieldUnitPoints);\r
+ dto.setDerivedUnitPoints(derivedUnitPoints);\r
+ dto.setOccurrenceQuery(queryString);\r
+\r
+ logger.info(queryString);\r
+\r
+ return dto;\r
}\r
\r
/**\r
return (char)ascii;\r
}\r
\r
+ /**\r
+ * @param statusColorJson for example: {@code {"n":"#ff0000","p":"#ffff00"}}\r
+ * @return\r
+ * @throws IOException\r
+ * @throws JsonParseException\r
+ * @throws JsonMappingException\r
+ */\r
+ public static Map<PresenceAbsenceTerm, Color> buildStatusColorMap(String statusColorJson, ITermService termService) throws IOException, JsonParseException,\r
+ JsonMappingException {\r
+\r
+ Map<PresenceAbsenceTerm, Color> presenceAbsenceTermColors = null;\r
+ if(StringUtils.isNotEmpty(statusColorJson)){\r
+\r
+ ObjectMapper mapper = new ObjectMapper();\r
+ // TODO cache the color maps to speed this up?\r
+\r
+ TypeFactory typeFactory = mapper.getTypeFactory();\r
+ MapType mapType = typeFactory.constructMapType(HashMap.class, String.class, String.class);\r
+\r
+ Map<String,String> statusColorMap = mapper.readValue(statusColorJson, mapType);\r
+ UUID presenceTermVocabUuid = PresenceAbsenceTerm.NATIVE().getVocabulary().getUuid();\r
+ presenceAbsenceTermColors = new HashMap<PresenceAbsenceTerm, Color>();\r
+ PresenceAbsenceTerm paTerm = null;\r
+ for(String statusId : statusColorMap.keySet()){\r
+ try {\r
+ Color color = Color.decode(statusColorMap.get(statusId));\r
+ paTerm = termService.findByIdInVocabulary(statusId, presenceTermVocabUuid, PresenceAbsenceTerm.class);\r
+ if(paTerm != null){\r
+ presenceAbsenceTermColors.put(paTerm, color);\r
+ }\r
+ } catch (NumberFormatException e){\r
+ logger.error("Cannot decode color", e);\r
+ }\r
+ }\r
+ }\r
+ return presenceAbsenceTermColors;\r
+ }\r
+\r
+\r
+ /**\r
+ * @param filteredDistributions\r
+ * @param recipe\r
+ * @param hideMarkedAreas\r
+ * @param langs\r
+ * @return\r
+ */\r
+ public static CondensedDistribution getCondensedDistribution(Collection<Distribution> filteredDistributions,\r
+ CondensedDistributionRecipe recipe, List<Language> langs) {\r
+ ICondensedDistributionComposer composer;\r
+ if(recipe == null) {\r
+ throw new NullPointerException("parameter recipe must not be null");\r
+ }\r
+ try {\r
+ composer = recipe.newCondensedDistributionComposerInstance();\r
+ } catch (InstantiationException e) {\r
+ throw new RuntimeException(e);\r
+ } catch (IllegalAccessException e) {\r
+ throw new RuntimeException(e);\r
+ }\r
+ CondensedDistribution condensedDistribution = composer.createCondensedDistribution(\r
+ filteredDistributions, langs);\r
+ return condensedDistribution;\r
+ }\r
+\r
}\r