/*
* Copyright (C) 2010-2012 Stichting Akvo (Akvo Foundation)
*
* This file is part of Akvo FLOW.
*
* Akvo FLOW is free software: you can redistribute it and modify it under the terms of
* the GNU Affero General Public License (AGPL) as published by the Free Software Foundation,
* either version 3 of the License or any later version.
*
* Akvo FLOW is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License included below for more details.
*
* The full license text can also be seen at <http://www.gnu.org/licenses/agpl.html>.
*/
package org.waterforpeople.mapping.app.web;
import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.velocity.VelocityContext;
import org.waterforpeople.mapping.dao.AccessPointDao;
import org.waterforpeople.mapping.dao.GeoRegionDAO;
import org.waterforpeople.mapping.domain.AccessPoint;
import org.waterforpeople.mapping.domain.AccessPoint.AccessPointType;
import org.waterforpeople.mapping.domain.GeoRegion;
import org.waterforpeople.mapping.domain.TechnologyType;
import org.waterforpeople.mapping.helper.AccessPointHelper;
import com.gallatinsystems.common.Constants;
import com.gallatinsystems.common.util.PropertyUtil;
import com.gallatinsystems.common.util.VelocityUtil;
import com.gallatinsystems.editorial.dao.EditorialPageDao;
import com.gallatinsystems.editorial.domain.EditorialPage;
import com.gallatinsystems.framework.dao.BaseDAO;
import com.gallatinsystems.standards.dao.LOSScoreToStatusMappingDao;
import com.gallatinsystems.standards.dao.LevelOfServiceScoreDao;
import com.gallatinsystems.standards.domain.LOSScoreToStatusMapping;
import com.gallatinsystems.standards.domain.LevelOfServiceScore;
import com.gallatinsystems.standards.domain.Standard.StandardType;
import com.gallatinsystems.surveyal.domain.SurveyalValue;
import com.gallatinsystems.surveyal.domain.SurveyedLocale;
import com.google.appengine.api.datastore.Key;
public class KMLGenerator {
private static final String IMAGE_ROOT = "mapiconimageroot";
private static final Logger log = Logger.getLogger(KMLGenerator.class
.getName());
public static final String GOOGLE_EARTH_DISPLAY = "googleearth";
// public static final String WATER_POINT_FUNCTIONING_GREEN_ICON_URL =
// PropertyUtil
// .getProperty(IMAGE_ROOT) + "/images/iconGreen36.png";
// public static final String WATER_POINT_FUNCTIONING_YELLOW_ICON_URL =
// PropertyUtil
// .getProperty(IMAGE_ROOT) + "/images/iconYellow36.png";
// public static final String WATER_POINT_FUNCTIONING_RED_ICON_URL =
// PropertyUtil
// .getProperty(IMAGE_ROOT) + "/images/iconRed36.png";
public static final String WATER_POINT_FUNCTIONING_GREEN_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/glassGreen32.png";
public static final String WATER_POINT_FUNCTIONING_YELLOW_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/glassOrange32.png";
public static final String WATER_POINT_FUNCTIONING_RED_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/glassRed32.png";
public static final String WATER_POINT_FUNCTIONING_BLACK_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/iconBlack36.png";
public static final String PUBLIC_INSTITUTION_FUNCTIONING_GREEN_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/houseGreen36.png";
public static final String PUBLIC_INSTITUTION_FUNCTIONING_YELLOW_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/houseYellow36.png";
public static final String PUBLIC_INSTITUTION_FUNCTIONING_RED_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/houseRed36.png";
public static final String PUBLIC_INSTITUTION_FUNCTIONING_BLACK_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/houseBlack36.png";
public static final String PUBLIC_INSTITUTION_FUNCTION_BLACK_ICON_URL_2 = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/iconBlack36.png";
public static final String SCHOOL_INSTITUTION_FUNCTIONING_GREEN_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/pencilGreen36.png";
public static final String SCHOOL_INSTITUTION_FUNCTIONING_YELLOW_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/pencilYellow36.png";
public static final String SCHOOL_INSTITUTION_FUNCTIONING_RED_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/pencilRed36.png";
public static final String SCHOOL_INSTITUTION_FUNCTIONING_BLACK_ICON_URL = PropertyUtil
.getProperty(IMAGE_ROOT) + "/images/pencilBlack36.png";
public static final Boolean useScore = Boolean.parseBoolean(PropertyUtil
.getProperty("scoreAPFlag"));
public static final String ORGANIZATION_KEY = "organization";
public static final String ORGANIZATION = PropertyUtil
.getProperty("organization");
private static final ThreadLocal<DateFormat> LONG_DATE_FORMAT = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("dd-MM-yyyy HH:mm:ss z");
};
};
private static final Map<String, String> ICON_TYPE_MAPPING;
private static final Map<String, String> ICON_COLOR_MAPPING;
private static final String IMAGE_PREFIX = PropertyUtil
.getProperty(IMAGE_ROOT);
private static final String DEFAULT = "DEFAULT";
public static final String defaultPhotoCaption = PropertyUtil
.getProperty("defaultPhotoCaption");
private static final String DYNAMIC_SCORING_FLAG = "scoreAPDynamicFlag";
static {
ICON_TYPE_MAPPING = new HashMap<String, String>();
ICON_TYPE_MAPPING.put("WaterPoint", "glass");
ICON_TYPE_MAPPING.put("PublicInstitution", "house");
ICON_TYPE_MAPPING.put("Household", "house");
ICON_TYPE_MAPPING.put("School", "pencil");
ICON_TYPE_MAPPING.put("Trawler", "glass");
ICON_TYPE_MAPPING.put(DEFAULT, "glass");
ICON_COLOR_MAPPING = new HashMap<String, String>();
ICON_COLOR_MAPPING.put(DEFAULT, "Black36.png");
ICON_COLOR_MAPPING.put("FUNCTIONING_OK", "Green36.png");
ICON_COLOR_MAPPING.put("FUNCTIONING_HIGH", "Green36.png");
ICON_COLOR_MAPPING.put("FUNCTIONING_OK", "Yellow36.png");
ICON_COLOR_MAPPING.put("FUNCTIONING_WITH_PROBLEMS", "Yellow36.png");
ICON_COLOR_MAPPING.put("BROKEN_DOWN", "Black36.png");
ICON_COLOR_MAPPING.put("NO_IMPROVED_SYSTEM", "Black36.png");
}
/**
* forms the url for the placemark image based on the status
*
* @param type
* @param status
* @return
*/
public static String getMarkerImageUrl(String type, String status) {
String url = KMLGenerator.IMAGE_PREFIX + "/images/";
String typePart = KMLGenerator.ICON_TYPE_MAPPING
.get(type != null ? type : KMLGenerator.DEFAULT);
if (typePart == null) {
typePart = KMLGenerator.ICON_TYPE_MAPPING.get(KMLGenerator.DEFAULT);
}
url += typePart;
String statusPart = KMLGenerator.ICON_COLOR_MAPPING
.get(status != null ? status : KMLGenerator.DEFAULT);
if (statusPart == null) {
statusPart = KMLGenerator.ICON_COLOR_MAPPING
.get(KMLGenerator.DEFAULT);
}
url += statusPart;
return url;
}
public static final String useLongDates = PropertyUtil
.getProperty("useLongDates");
public KMLGenerator() {
}
public String generateRegionDocumentString(String regionVMName) {
String regionKML = generateRegionOutlines(regionVMName);
return regionKML;
}
public String generateDocument(String placemarksVMName) {
return generateDocument(placemarksVMName, Constants.ALL_RESULTS);
}
public String generateDocument(String placemarksVMName, String countryCode) {
try {
VelocityContext context = new VelocityContext();
String placemarks = generatePlacemarks(placemarksVMName,
countryCode);
context.put("folderContents", placemarks);
context.put("regionPlacemark", generateRegionOutlines("Regions.vm"));
return mergeContext(context, "Document.vm");
} catch (Exception ex) {
log.log(Level.SEVERE, "Could create kml", ex);
}
return null;
}
@SuppressWarnings("unused")
private String generateFolderContents(
HashMap<String, ArrayList<String>> contents, String vmName)
throws Exception {
VelocityContext context = new VelocityContext();
StringBuilder techFolders = new StringBuilder();
for (Entry<String, ArrayList<String>> techItem : contents.entrySet()) {
String key = techItem.getKey();
StringBuilder sbFolderPl = new StringBuilder();
for (String placemark : techItem.getValue()) {
sbFolderPl.append(placemark);
}
context.put("techFolderName", key);
context.put("techPlacemarks", sbFolderPl);
techFolders.append(mergeContext(context, "techFolders.vm"));
}
context.put("techFolders", techFolders.toString());
return mergeContext(context, vmName);
}
public void generateCountryOrderedPlacemarks(String vmName,
String countryCode, String technologyType) {
}
public HashMap<String, ArrayList<String>> generateCountrySpecificPlacemarks(
String vmName, String countryCode) {
if (countryCode.equals("MW")) {
HashMap<String, ArrayList<AccessPoint>> techMap = new HashMap<String, ArrayList<AccessPoint>>();
BaseDAO<TechnologyType> techDAO = new BaseDAO<TechnologyType>(
TechnologyType.class);
List<TechnologyType> techTypeList = (List<TechnologyType>) techDAO
.list(Constants.ALL_RESULTS);
AccessPointDao apDao = new AccessPointDao();
List<AccessPoint> waterAPList = apDao.searchAccessPoints(
countryCode, null, null, null, "WATER_POINT", null, null,
null, null, null, null, Constants.ALL_RESULTS);
for (TechnologyType techType : techTypeList) {
// log.info("TechnologyType: " + techType.getName());
ArrayList<AccessPoint> techTypeAPList = new ArrayList<AccessPoint>();
for (AccessPoint item : waterAPList) {
if (techType.getName().toLowerCase()
.equals("unimproved waterpoint")
&& item.getTypeTechnologyString().toLowerCase()
.contains("unimproved waterpoint")) {
techTypeAPList.add(item);
} else if (item.getTypeTechnologyString().equals(
techType.getName())) {
techTypeAPList.add(item);
}
}
techMap.put(techType.getName(), techTypeAPList);
}
List<AccessPoint> sanitationAPList = apDao.searchAccessPoints(
countryCode, null, null, null, "SANITATION_POINT", null,
null, null, null, null, null, Constants.ALL_RESULTS);
HashMap<String, AccessPoint> sanitationMap = new HashMap<String, AccessPoint>();
for (AccessPoint item : sanitationAPList) {
sanitationMap.put(item.getGeocells().toString(), item);
}
sanitationAPList = null;
HashMap<String, ArrayList<String>> techPlacemarksMap = new HashMap<String, ArrayList<String>>();
for (Entry<String, ArrayList<AccessPoint>> item : techMap
.entrySet()) {
String key = item.getKey();
ArrayList<String> placemarks = new ArrayList<String>();
for (AccessPoint waterAP : item.getValue()) {
AccessPoint sanitationAP = sanitationMap.get(waterAP
.getGeocells().toString());
if (sanitationAP != null) {
placemarks.add(buildMainPlacemark(waterAP,
sanitationAP, vmName));
} else {
log.info("No matching sanitation point found for "
+ waterAP.getLatitude() + ":"
+ waterAP.getLongitude() + ":"
+ waterAP.getCommunityName());
}
}
techPlacemarksMap.put(key, placemarks);
}
return techPlacemarksMap;
}
return null;
}
private HashMap<String, String> loadContextBindings(AccessPoint waterAP,
AccessPoint sanitationAP) {
// log.info(waterAP.getCommunityCode());
try {
HashMap<String, String> contextBindingsMap = new HashMap<String, String>();
if (waterAP.getCollectionDate() != null) {
String timestamp = DateFormatUtils.formatUTC(
waterAP.getCollectionDate(),
DateFormatUtils.ISO_DATE_FORMAT.getPattern());
String formattedDate = DateFormat.getDateInstance(
DateFormat.SHORT).format(waterAP.getCollectionDate());
contextBindingsMap.put("collectionDate", formattedDate);
contextBindingsMap.put("timestamp", timestamp);
String collectionYear = new SimpleDateFormat("yyyy")
.format(waterAP.getCollectionDate());
contextBindingsMap.put("collectionYear", collectionYear);
} else {
// TODO: This block is a problem. We should never have data
// without a collectionDate so this is a hack so it display
// properly until I can sort out what to do with this data.
String timestamp = DateFormatUtils.formatUTC(new Date(),
DateFormatUtils.ISO_DATE_FORMAT.getPattern());
String formattedDate = DateFormat.getDateInstance(
DateFormat.SHORT).format(new Date());
contextBindingsMap.put("collectionDate", formattedDate);
contextBindingsMap.put("timestamp", timestamp);
String collectionYear = new SimpleDateFormat("yyyy")
.format(new Date());
contextBindingsMap.put("collectionYear", collectionYear);
}
contextBindingsMap.put("communityCode",
encodeNullDefault(waterAP.getCommunityCode(), "Unknown"));
contextBindingsMap.put("communityName",
encodeNullDefault(waterAP.getCommunityName(), "Unknown"));
contextBindingsMap.put(
"typeOfWaterPointTechnology",
encodeNullDefault(waterAP.getTypeTechnologyString(),
"Unknown"));
contextBindingsMap.put(
"constructionDateOfWaterPoint",
encodeNullDefault(waterAP.getConstructionDateYear(),
"Unknown"));
contextBindingsMap.put(
"numberOfHouseholdsUsingWaterPoint",
encodeNullDefault(
waterAP.getNumberOfHouseholdsUsingPoint(),
"Unknown"));
contextBindingsMap.put("costPer20ML",
encodeNullDefault(waterAP.getCostPer(), "Unknown"));
contextBindingsMap.put(
"farthestHouseholdFromWaterPoint",
encodeNullDefault(waterAP.getFarthestHouseholdfromPoint(),
"Unknown"));
contextBindingsMap.put(
"currentManagementStructureOfWaterPoint",
encodeNullDefault(
waterAP.getCurrentManagementStructurePoint(),
"Unknown"));
contextBindingsMap.put("waterSystemStatus",
encodeStatusString(waterAP.getPointStatus()));
contextBindingsMap.put("photoUrl",
encodeNullDefault(waterAP.getPhotoURL(), "Unknown"));
contextBindingsMap
.put("waterPointPhotoCaption",
encodeNullDefault(waterAP.getPointPhotoCaption(),
"Unknown"));
contextBindingsMap.put(
"primarySanitationTechnology",
encodeNullDefault(sanitationAP.getTypeTechnologyString(),
"Unknown"));
contextBindingsMap.put(
"percentageOfHouseholdsWithImprovedSanitation",
encodeNullDefault(
sanitationAP.getNumberOfHouseholdsUsingPoint(),
"Unknown"));
contextBindingsMap.put("photoOfPrimarySanitationtechnology",
encodeNullDefault(sanitationAP.getPhotoURL(), "Unknown"));
contextBindingsMap.put(
"sanitationPhotoCaption",
encodeNullDefault(sanitationAP.getPointPhotoCaption(),
"Unknown"));
contextBindingsMap.put("footer",
encodeNullDefault(waterAP.getFooter(), "Unknown"));
contextBindingsMap.put(
"longitude",
encodeNullDefault(waterAP.getLongitude().toString(),
"Unknown"));
contextBindingsMap.put(
"latitude",
encodeNullDefault(waterAP.getLatitude().toString(),
"Unknown"));
contextBindingsMap.put("altitude",
encodeNullDefault(waterAP.getAltitude().toString(), "0.0"));
contextBindingsMap.put(
"pinStyle",
encodePinStyle(waterAP.getPointType(),
waterAP.getPointStatus()));
return contextBindingsMap;
} catch (NullPointerException nex) {
log.log(Level.SEVERE, "Could not load context bindings", nex);
}
return null;
}
private String buildMainPlacemark(AccessPoint waterAP,
AccessPoint sanitationAP, String vmName) {
HashMap<String, String> contextBindingsMap = loadContextBindings(
waterAP, sanitationAP);
VelocityContext context = new VelocityContext();
for (Map.Entry<String, String> entry : contextBindingsMap.entrySet()) {
context.put(entry.getKey(), entry.getValue());
}
StringBuilder sb = new StringBuilder();
String output = null;
try {
output = mergeContext(context, vmName);
} catch (Exception e) {
log.log(Level.SEVERE, "Could not build main placemark", e);
}
sb.append(output);
return sb.toString();
}
private String encodeNullDefault(Object value, String defaultMissingVal) {
try {
if (value != null) {
return value.toString();
} else {
return defaultMissingVal;
}
} catch (Exception ex) {
// log.info("value that generated nex: " + value);
log.log(Level.SEVERE, "Could not encode null default", ex);
}
return null;
}
public String generatePlacemarks(String vmName, String countryCode) {
return generatePlacemarks(vmName, countryCode, GOOGLE_EARTH_DISPLAY);
}
public String generatePlacemarks(String vmName, String countryCode,
String display) {
StringBuilder sb = new StringBuilder();
AccessPointDao apDAO = new AccessPointDao();
List<AccessPoint> entries = null;
if (countryCode.equals(Constants.ALL_RESULTS))
entries = apDAO.list(Constants.ALL_RESULTS);
else
entries = apDAO.searchAccessPoints(countryCode, null, null, null,
null, null, null, null, null, null, null,
Constants.ALL_RESULTS);
// loop through accessPoints and bind to variables
int i = 0;
try {
for (AccessPoint ap : entries) {
if (!ap.getPointType().equals(
AccessPoint.AccessPointType.SANITATION_POINT)) {
try {
VelocityContext context = new VelocityContext();
String pmContents = bindPlacemark(
ap,
display.equalsIgnoreCase(GOOGLE_EARTH_DISPLAY) ? "placemarkGoogleEarth.vm"
: "placemarkExternalMap.vm", display,
null);
if (ap.getCollectionDate() != null) {
String timestamp = DateFormatUtils.formatUTC(ap
.getCollectionDate(),
DateFormatUtils.ISO_DATE_FORMAT
.getPattern());
String formattedDate = DateFormat.getDateInstance(
DateFormat.SHORT).format(
ap.getCollectionDate());
context.put("collectionDate", formattedDate);
context.put("timestamp", timestamp);
String collectionYear = new SimpleDateFormat("yyyy")
.format(ap.getCollectionDate());
context.put("collectionYear", collectionYear);
} else {
String timestamp = DateFormatUtils.formatUTC(
new Date(), DateFormatUtils.ISO_DATE_FORMAT
.getPattern());
String formattedDate = DateFormat.getDateInstance(
DateFormat.SHORT).format(new Date());
context.put("collectionDate", formattedDate);
context.put("timestamp", timestamp);
}
if (ap.getCommunityName() == null) {
context.put("communityName", "Unknown");
} else {
context.put("communityName", ap.getCommunityName());
}
if (ap.getCommunityCode() != null)
context.put("communityCode", ap.getCommunityCode());
else
context.put("communityCode", "Unknown" + new Date());
// Need to check this
if (ap.getPointType() != null) {
if (Boolean.parseBoolean(PropertyUtil
.getProperty(DYNAMIC_SCORING_FLAG))) {
} else {
encodeStatusString(ap, context);
context.put(
"pinStyle",
encodePinStyle(ap.getPointType(),
ap.getPointStatus()));
}
} else {
context.put("pinStyle", "waterpushpinblk");
}
context.put("latitude", ap.getLatitude());
context.put("longitude", ap.getLongitude());
if (ap.getAltitude() == null)
context.put("altitude", 0.0);
else
context.put("altitude", ap.getAltitude());
context.put("balloon", pmContents);
String placemarkStr = mergeContext(context, vmName);
sb.append(placemarkStr);
i++;
} catch (Exception e) {
log.log(Level.INFO, "Error generating placemarks: "
+ ap.getCommunityCode(), e);
}
}
}
} catch (Exception ex) {
log.log(Level.SEVERE, "Bad access point: "
+ entries.get(i + 1).toString());
}
return sb.toString();
}
/**
* attempts to merge the context with the template. The template will be resolved from cache
* and, if there is a miss, it will use the EditorialPageDao as the templateBackingStore. If the
* template is still not found, it will attempt to use a static template file from the
* application context.
*
* @param context
* @param template
* @return
* @throws Exception
*/
private String mergeContext(VelocityContext context, String template)
throws Exception {
return VelocityUtil.mergeContext(context, template,
new VelocityUtil.TemplateCacheBackingStore() {
@Override
public String getByKey(String key) {
EditorialPageDao edDao = new EditorialPageDao();
EditorialPage page = edDao.findByTargetPage(key);
if (page != null) {
return page.getTemplate().getValue();
} else {
return null;
}
}
});
}
public String bindPlacemark(SurveyedLocale ap, String vmName, String display)
throws Exception {
if (ap.getCountryCode() == null) {
ap.setCountryCode("Unknown");
}
VelocityContext context = new VelocityContext();
context.put("organization", ORGANIZATION);
if (display != null) {
context.put("display", display);
}
context.put("countryCode", ap.getCountryCode());
if (ap.getLastSurveyedDate() != null) {
String timestamp = DateFormatUtils.formatUTC(
ap.getLastSurveyedDate(),
DateFormatUtils.ISO_DATE_FORMAT.getPattern());
String formattedDate = null;
if ("true".equals(useLongDates)) {
formattedDate = LONG_DATE_FORMAT.get().format(ap
.getLastSurveyedDate());
} else {
formattedDate = DateFormat.getDateInstance(DateFormat.SHORT)
.format(ap.getLastSurveyedDate());
}
context.put("collectionDate", formattedDate);
context.put("timestamp", timestamp);
String collectionYear = new SimpleDateFormat("yyyy").format(ap
.getLastSurveyedDate());
context.put("collectionYear", collectionYear);
} else {
String timestamp = DateFormatUtils.formatUTC(
ap.getCreatedDateTime(),
DateFormatUtils.ISO_DATE_FORMAT.getPattern());
String formattedDate = null;
if ("true".equals(useLongDates)) {
formattedDate = LONG_DATE_FORMAT.get()
.format(ap.getCreatedDateTime());
} else {
formattedDate = DateFormat.getDateInstance(DateFormat.SHORT)
.format(ap.getCreatedDateTime());
}
context.put("collectionDate", formattedDate);
context.put("timestamp", timestamp);
}
if (ap.getIdentifier() != null) {
context.put("identifier", ap.getIdentifier());
} else {
context.put("identifier", "Unknown" + new Date());
}
boolean foundPhoto = false;
boolean foundStatus = false;
if (ap.getSurveyalValues() != null) {
// TODO: handle case where we have multiple values (with different
// dates) for same question/metric
List<SurveyalValue> valuesToBind = new ArrayList<SurveyalValue>(
ap.getSurveyalValues());
for (SurveyalValue val : ap.getSurveyalValues()) {
if (val.getQuestionType() != null) {
if (!"free_text".equalsIgnoreCase(val.getQuestionType())
&& !"option"
.equalsIgnoreCase(val.getQuestionType())) {
valuesToBind.remove(val);
}
}
if (val.getStringValue() == null) {
valuesToBind.remove(val);
} else if (val.getStringValue().trim().toLowerCase()
.endsWith(".jpg")
|| val.getStringValue().trim().toLowerCase()
.endsWith(".jpeg")) {
String urlBase = val.getStringValue();
if (urlBase.contains("/")) {
urlBase = urlBase
.substring(urlBase.lastIndexOf("/") + 1);
}
if (!urlBase.toLowerCase().startsWith("http")) {
if (urlBase.endsWith("/")) {
urlBase = urlBase
.substring(0, urlBase.length() - 1);
}
urlBase = PropertyUtil.getProperty("photo_url_root")
+ urlBase;
}
context.put("photoUrl", urlBase);
foundPhoto = true;
valuesToBind.remove(val);
} else if (ap.getCurrentStatus() == null) {
if (val.getMetricName() != null
&& val.getMetricName().trim().toLowerCase()
.contains("status")) {
context.put("waterSystemStatus", val.getStringValue());
foundStatus = true;
}
}
}
context.put("surveyalValues", valuesToBind);
}
if (ap.getCurrentStatus() != null) {
try {
context.put("waterSystemStatus",
encodeStatusString(AccessPoint.Status.valueOf(ap
.getCurrentStatus())));
} catch (Exception e) {
context.put("waterSystemStatus", "Unknown");
}
} else {
if (!foundStatus) {
context.put("waterSystemStatus", "Unknown");
}
}
// TODO: parameterize the default logo
if (!foundPhoto) {
context.put("photoUrl",
"http://waterforpeople.s3.amazonaws.com/images/wfplogo.jpg");
}
context.put("latitude", ap.getLatitude());
context.put("longitude", ap.getLongitude());
if (ap.getLocaleType() != null) {
context.put("type", ap.getLocaleType());
} else {
context.put("type", "water");
}
String output = mergeContext(context, vmName);
context = null;
return output;
}
public String bindPlacemark(AccessPoint ap, String vmName, String display,
StandardType standardType) throws Exception {
// if (ap.getCountryCode() != null && !ap.getCountryCode().equals("MW"))
// {
if (display != null
&& display.trim().equalsIgnoreCase(GOOGLE_EARTH_DISPLAY)) {
vmName = "placemarkGoogleEarth.vm";
}
if (ap.getCountryCode() == null)
ap.setCountryCode("Unknown");
if (ap.getCountryCode() != null) {
VelocityContext context = new VelocityContext();
context.put("organization", ORGANIZATION);
if (display != null) {
context.put("display", display);
}
context.put("countryCode", ap.getCountryCode());
if (ap.getCollectionDate() != null) {
String timestamp = DateFormatUtils.formatUTC(
ap.getCollectionDate(),
DateFormatUtils.ISO_DATE_FORMAT.getPattern());
String formattedDate = DateFormat.getDateInstance(
DateFormat.SHORT).format(ap.getCollectionDate());
context.put("collectionDate", formattedDate);
context.put("timestamp", timestamp);
String collectionYear = new SimpleDateFormat("yyyy").format(ap
.getCollectionDate());
context.put("collectionYear", collectionYear);
} else {
String timestamp = DateFormatUtils.formatUTC(
ap.getCreatedDateTime(),
DateFormatUtils.ISO_DATE_FORMAT.getPattern());
String formattedDate = DateFormat.getDateInstance(
DateFormat.SHORT).format(ap.getCreatedDateTime());
context.put("collectionDate", formattedDate);
context.put("timestamp", timestamp);
}
if (ap.getCommunityCode() != null)
context.put("communityCode", ap.getCommunityCode());
else
context.put("communityCode", "Unknown" + new Date());
if (ap.getWaterForPeopleProjectFlag() != null) {
context.put("waterForPeopleProject",
encodeBooleanDisplay(ap.getWaterForPeopleProjectFlag()));
} else {
context.put("waterForPeopleProject", "null");
}
if (ap.getCurrentProblem() != null) {
context.put("currentProblem", ap.getCurrentProblem());
} else {
context.put("currentProblem", ap.getCurrentProblem());
}
if (ap.getWaterForPeopleRole() != null) {
context.put("waterForPeopleRole", ap.getWaterForPeopleRole());
} else {
context.put("waterForPeopleRole", "null");
}
if (ap.getPhotoURL() != null && ap.getPhotoURL().trim() != "")
context.put("photoUrl", ap.getPhotoURL());
else
context.put("photoUrl",
"http://waterforpeople.s3.amazonaws.com/images/wfplogo.jpg");
if (ap.getPointType() != null) {
if (ap.getPointType().equals(
AccessPoint.AccessPointType.WATER_POINT)) {
context.put("typeOfPoint", "Water");
context.put("type", "water");
} else if (ap.getPointType().equals(
AccessPointType.SANITATION_POINT)) {
context.put("typeOfPoint", "Sanitation");
context.put("type", "sanitation");
} else if (ap.getPointType().equals(
AccessPointType.PUBLIC_INSTITUTION)) {
context.put("typeOfPoint", "Public Institutions");
context.put("type", "public_institutions");
} else if (ap.getPointType().equals(
AccessPointType.HEALTH_POSTS)) {
context.put("typeOfPoint", "Health Posts");
context.put("type", "health_posts");
} else if (ap.getPointType().equals(AccessPointType.SCHOOL)) {
context.put("typeOfPoint", "School");
context.put("type", "school");
}
} else {
context.put("typeOfPoint", "Water");
context.put("type", "water");
}
if (ap.getTypeTechnologyString() == null) {
context.put("primaryTypeTechnology", "Unknown");
} else {
context.put("primaryTypeTechnology",
ap.getTypeTechnologyString());
}
if (ap.getHasSystemBeenDown1DayFlag() == null) {
context.put("down1DayFlag", "Unknown");
} else {
context.put("down1DayFlag",
encodeBooleanDisplay(ap.getHasSystemBeenDown1DayFlag()));
}
if (ap.getInstitutionName() == null) {
context.put("institutionName", "Unknown");
} else {
context.put("institutionName", ap.getInstitutionName());
}
if (ap.getExtimatedPopulation() != null) {
context.put("estimatedPopulation", ap.getExtimatedPopulation());
} else {
context.put("estimatedPopulation", "null");
}
if (ap.getConstructionDateYear() == null
|| ap.getConstructionDateYear().trim().equals("")) {
context.put("constructionDateOfWaterPoint", "Unknown");
} else {
String constructionDateYear = ap.getConstructionDateYear();
if (constructionDateYear.contains(".0")) {
constructionDateYear = constructionDateYear.replace(".0",
"");
}
context.put("constructionDateOfWaterPoint",
constructionDateYear);
}
if (ap.getNumberOfHouseholdsUsingPoint() != null) {
context.put("numberOfHouseholdsUsingWaterPoint",
ap.getNumberOfHouseholdsUsingPoint());
} else {
context.put("numberOfHouseholdsUsingWaterPoint", "null");
}
if (ap.getCostPer() == null) {
context.put("costPer", "N/A");
} else {
context.put("costPer", ap.getCostPer());
}
if (ap.getFarthestHouseholdfromPoint() == null
|| ap.getFarthestHouseholdfromPoint().trim().equals("")) {
context.put("farthestHouseholdfromWaterPoint", "N/A");
} else {
context.put("farthestHouseholdfromWaterPoint",
ap.getFarthestHouseholdfromPoint());
}
if (ap.getCurrentManagementStructurePoint() == null) {
context.put("currMgmtStructure", "N/A");
} else {
context.put("currMgmtStructure",
ap.getCurrentManagementStructurePoint());
}
if (ap.getPointPhotoCaption() == null
|| ap.getPointPhotoCaption().trim().equals("")) {
context.put("waterPointPhotoCaption", defaultPhotoCaption);
} else {
context.put("waterPointPhotoCaption", ap.getPointPhotoCaption());
}
if (ap.getCommunityName() == null) {
context.put("communityName", "Unknown");
} else {
context.put("communityName", ap.getCommunityName());
}
if (ap.getHeader() == null) {
context.put("header", "Water For People");
} else {
context.put("header", ap.getHeader());
}
if (ap.getFooter() == null) {
context.put("footer", "Water For People");
} else {
context.put("footer", ap.getFooter());
}
if (ap.getPhotoName() == null) {
context.put("photoName", "Water For People");
} else {
context.put("photoName", ap.getPhotoName());
}
// if (ap.getCountryCode() == "RW") {
if (ap.getMeetGovtQualityStandardFlag() == null) {
context.put("meetGovtQualityStandardFlag", "N/A");
} else {
context.put("meetGovtQualityStandardFlag",
encodeBooleanDisplay(ap
.getMeetGovtQualityStandardFlag()));
}
// } else {
// context.put("meetGovtQualityStandardFlag", "unknown");
// }
if (ap.getMeetGovtQuantityStandardFlag() == null) {
context.put("meetGovtQuantityStandardFlag", "N/A");
} else {
context.put("meetGovtQuantityStandardFlag",
encodeBooleanDisplay(ap
.getMeetGovtQuantityStandardFlag()));
}
if (ap.getWhoRepairsPoint() == null) {
context.put("whoRepairsPoint", "N/A");
} else {
context.put("whoRepairsPoint", ap.getWhoRepairsPoint());
}
if (ap.getSecondaryTechnologyString() == null) {
context.put("secondaryTypeTechnology", "N/A");
} else {
context.put("secondaryTypeTechnology",
ap.getSecondaryTechnologyString());
}
if (ap.getProvideAdequateQuantity() == null) {
context.put("provideAdequateQuantity", "N/A");
} else {
context.put("provideAdequateQuantity",
encodeBooleanDisplay(ap.getProvideAdequateQuantity()));
}
if (ap.getBalloonTitle() == null) {
context.put("title", "Water For People");
} else {
context.put("title", ap.getBalloonTitle());
}
if (ap.getProvideAdequateQuantity() == null) {
context.put("provideAdequateQuantity", "N/A");
} else {
context.put("provideAdequateQuantity",
encodeBooleanDisplay(ap.getProvideAdequateQuantity()));
}
if (ap.getQualityDescription() != null) {
context.put("qualityDescription", ap.getQualityDescription());
}
if (ap.getQuantityDescription() != null) {
context.put("quantityDescription", ap.getQuantityDescription());
}
if (ap.getSub1() != null) {
context.put("sub1", ap.getSub1());
}
if (ap.getSub2() != null) {
context.put("sub2", ap.getSub2());
}
if (ap.getSub3() != null) {
context.put("sub3", ap.getSub3());
}
if (ap.getSub4() != null) {
context.put("sub4", ap.getSub4());
}
if (ap.getSub5() != null) {
context.put("sub5", ap.getSub5());
}
if (ap.getSub6() != null) {
context.put("sub6", ap.getSub6());
}
if (ap.getAccessPointCode() != null) {
context.put("accessPointCode", ap.getAccessPointCode());
}
if (ap.getAccessPointUsage() != null) {
context.put("accessPointUsage", ap.getAccessPointUsage());
}
if (ap.getDescription() != null)
context.put("description", ap.getDescription());
else
context.put("description", "Unknown");
// Need to check this
if (ap.getPointType() != null) {
if (Boolean.parseBoolean(PropertyUtil
.getProperty(DYNAMIC_SCORING_FLAG))) {
TreeMap<String, String> combinedScore = fetchLevelOfServiceScoreStatus(ap);
for (Map.Entry<String, String> entry : combinedScore
.entrySet()) {
context.put(entry.getKey(), entry.getValue());
String style = null;
if (standardType != null) {
if (standardType
.equals(StandardType.WaterPointLevelOfService)
&& entry.getKey()
.equals(StandardType.WaterPointLevelOfService
.toString() + "-pinStyle")) {
style = entry.getValue();
} else if (standardType
.equals(StandardType.WaterPointSustainability)
&& entry.getKey()
.equals(StandardType.WaterPointSustainability
.toString() + "-pinStyle")) {
style = entry.getValue();
}
}
context.put("pinStyle", style);
}
} else {
encodeStatusString(ap, context);
context.put(
"pinStyle",
encodePinStyle(ap.getPointType(),
ap.getPointStatus()));
}
} else {
context.put("pinStyle", "waterpushpinblk");
}
String output = mergeContext(context, vmName);
context = null;
return output;
}
return null;
}
private TreeMap<String, String> fetchLevelOfServiceScoreStatus(
AccessPoint ap) {
TreeMap<String, String> losStyles = new TreeMap<String, String>();
LevelOfServiceScoreDao losScoreDao = new LevelOfServiceScoreDao();
List<LevelOfServiceScore> losList = losScoreDao.listByAccessPoint(ap
.getKey());
LOSScoreToStatusMappingDao losScoreToStatusMappingDao = new LOSScoreToStatusMappingDao();
for (LevelOfServiceScore losItem : losList) {
LOSScoreToStatusMapping losScoreToStatusMapping = losScoreToStatusMappingDao
.findByLOSScoreTypeAndScore(losItem.getScoreType(),
losItem.getScore());
losStyles.put(losScoreToStatusMapping.getLevelOfServiceScoreType()
.toString() + "-color", losScoreToStatusMapping.getColor()
.toString());
losStyles.put(losScoreToStatusMapping.getLevelOfServiceScoreType()
.toString() + "-desc",
losScoreToStatusMapping.getDescription());
losStyles.put(losScoreToStatusMapping.getLevelOfServiceScoreType()
.toString() + "-score", losItem.getScore().toString());
losStyles.put(losScoreToStatusMapping.getLevelOfServiceScoreType()
.toString() + "-pinstyle",
losScoreToStatusMapping.getIconStyle());
losStyles.put(losScoreToStatusMapping.getLevelOfServiceScoreType()
.toString() + "-iconSmallUrl",
losScoreToStatusMapping.getIconSmallUrl());
// losStyles.put(losScoreToStatusMapping.getLevelOfServiceScoreType().toString()+"details",
// losItem.getScoreDetails().toString());
}
return losStyles;
}
public String generateRegionOutlines(String vmName) {
StringBuilder sb = new StringBuilder();
GeoRegionDAO grDAO = new GeoRegionDAO();
List<GeoRegion> grList = grDAO.list();
try {
if (grList != null && grList.size() > 0) {
String currUUID = grList.get(0).getUuid();
VelocityContext context = new VelocityContext();
StringBuilder sbCoor = new StringBuilder();
// loop through GeoRegions and bind to variables
for (int i = 0; i < grList.size(); i++) {
GeoRegion gr = grList.get(i);
if (currUUID.equals(gr.getUuid())) {
sbCoor.append(gr.getLongitude() + ","
+ gr.getLatitiude() + "," + 0 + "\n");
} else {
currUUID = gr.getUuid();
context.put("coordinateString", sbCoor.toString());
sb.append(mergeContext(context, vmName));
context = new VelocityContext();
sbCoor = new StringBuilder();
sbCoor.append(gr.getLongitude() + ","
+ gr.getLatitiude() + "," + 0 + "\n");
}
}
context.put("coordinateString", sbCoor.toString());
sb.append(mergeContext(context, vmName));
return sb.toString();
}
} catch (Exception e) {
log.log(Level.SEVERE, "Error generating region outlines", e);
}
return "";
}
private String encodeBooleanDisplay(Boolean value) {
if (value) {
return "Yes";
} else {
return "No";
}
}
public LOSScoreToStatusMapping encodePinStyle(Key accessPointKey,
StandardType standardType) {
LevelOfServiceScoreDao losScoreDao = new LevelOfServiceScoreDao();
LevelOfServiceScore losScore = losScoreDao.findByAccessPoint(
accessPointKey, standardType);
LOSScoreToStatusMappingDao losMapDao = new LOSScoreToStatusMappingDao();
LOSScoreToStatusMapping losMapItem = losMapDao
.findByLOSScoreTypeAndScore(standardType, losScore.getScore());
return losMapItem;
}
public static String encodePinStyle(AccessPointType type,
AccessPoint.Status status) {
String prefix = "water";
if (AccessPointType.SANITATION_POINT == type) {
prefix = "sani";
} else if (AccessPointType.SCHOOL == type) {
prefix = "schwater";
} else if (AccessPointType.PUBLIC_INSTITUTION == type
|| AccessPointType.HEALTH_POSTS == type) {
prefix = "pubwater";
}
if (AccessPoint.Status.FUNCTIONING_HIGH == status) {
return prefix + "pushpingreen";
} else if (AccessPoint.Status.FUNCTIONING_OK == status
|| AccessPoint.Status.FUNCTIONING_WITH_PROBLEMS == status) {
return prefix + "pushpinyellow";
} else if (AccessPoint.Status.BROKEN_DOWN == status) {
return prefix + "pushpinred";
} else if (AccessPoint.Status.NO_IMPROVED_SYSTEM == status) {
return prefix + "pushpinblk";
} else {
return prefix + "pushpinblk";
}
}
public static String encodePinStyle(String type, String status) {
String prefix = "water";
if (type != null) {
if ("SanitationPoint".equalsIgnoreCase(type)) {
prefix = "sani";
} else if ("School".equalsIgnoreCase(type)) {
prefix = "schwater";
} else if ("PublicInstitution".equalsIgnoreCase(type)) {
prefix = "pubwater";
}
}
if ("FUNCTIONING_HIGH".equalsIgnoreCase(status)) {
return prefix + "pushpingreen";
} else if ("FUNCTIONING_OK".equalsIgnoreCase(status)
|| "FUNCTIONING_WITH_PROBLEMS".equalsIgnoreCase(status)) {
return prefix + "pushpinyellow";
} else if ("BROKEN_DOWN".equalsIgnoreCase(status)) {
return prefix + "pushpinred";
} else if ("NO_IMPROVED_SYSTEM".equalsIgnoreCase(status)) {
return prefix + "pushpinblk";
} else {
return prefix + "pushpinblk";
}
}
private String encodeStatusString(AccessPoint ap, VelocityContext context) {
AccessPoint.Status status = ap.getPointStatus();
if (ap.getCollectionDate() == null
|| ap.getCollectionDate().before(new Date("01/01/2011"))
|| !useScore) {
if (status != null) {
if (AccessPoint.Status.FUNCTIONING_HIGH == status) {
context.put("waterSystemStatus",
"Meets Government Standards");
return "System Functioning and Meets Government Standards";
} else if (AccessPoint.Status.FUNCTIONING_OK == status
|| AccessPoint.Status.FUNCTIONING_WITH_PROBLEMS == status) {
context.put("waterSystemStatus",
"Functioning but with Problems");
return "Functioning but with Problems";
} else if (AccessPoint.Status.BROKEN_DOWN == status) {
context.put("waterSystemStatus", "Broken-down system");
return "Broken-down system";
} else if (AccessPoint.Status.NO_IMPROVED_SYSTEM == status) {
context.put("waterSystemStatus", "No Improved System");
return "No Improved System";
} else {
context.put("waterSystemStatus", "Unknown");
return "Unknown";
}
} else {
context.put("waterSystemStatus", "Unknown");
return "Unknown";
}
} else {
String statusString = null;
try {
statusString = encodeStatusUsingScore(ap);
} catch (Exception ex) {
log.log(Level.INFO, "Couldn't score ap: " + ap.toString()
+ " " + ex);
}
if (statusString == null) {
statusString = "Unknown";
}
context.put("waterSystemStatus", statusString);
// will remove soon not necessary now that APs are getting scored on
// save
AccessPointDao apDao = new AccessPointDao();
apDao.save(ap);
return statusString;
}
}
private String encodeStatusString(AccessPoint.Status status) {
if (status == null) {
return "Unknown";
}
if (status.equals(AccessPoint.Status.FUNCTIONING_HIGH)) {
return "System Functioning and Meets Government Standards";
} else if (status.equals(AccessPoint.Status.FUNCTIONING_OK)
|| status.equals(AccessPoint.Status.FUNCTIONING_WITH_PROBLEMS)) {
return "Functioning but with Problems";
} else if (status.equals(AccessPoint.Status.BROKEN_DOWN)) {
return "Broken-down system";
} else if (status.equals(AccessPoint.Status.NO_IMPROVED_SYSTEM)) {
return "No Improved System";
} else {
return "Unknown";
}
}
public String encodeStatusUsingScore(AccessPoint ap)
throws InvocationTargetException, NoSuchMethodException {
Integer score = AccessPointHelper.scoreAccessPoint(ap).getScore();
new AccessPointHelper().scoreAccessPointDynamic(ap).getScore();
if (score == 0) {
return "No Improved System";
} else if (score >= 1 && score <= 2) {
return "Basic Level Service";
} else if (score >= 3 && score <= 4) {
return "Intermediate Level Service";
} else if (score >= 5) {
return "High Level Service";
} else {
return "Unknown";
}
}
}