package com.esri.geoevent.solutions.processor.queryreport; /* * #%L * Esri :: AGES :: Solutions :: Processor :: Geometry * $Id:$ * $HeadURL:$ * %% * Copyright (C) 2013 - 2014 Esri * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.net.URL; import java.net.URLEncoder; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.HttpClientBuilder; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.type.TypeFactory; import org.codehaus.jackson.type.TypeReference; import org.joda.time.DateTime; import com.esri.core.geometry.Envelope; import com.esri.core.geometry.Geometry; import com.esri.core.geometry.GeometryEngine; import com.esri.core.geometry.LinearUnit; import com.esri.core.geometry.MapGeometry; import com.esri.core.geometry.MultiPath; import com.esri.core.geometry.Point; import com.esri.core.geometry.Polygon; import com.esri.core.geometry.Polyline; import com.esri.core.geometry.Segment; import com.esri.core.geometry.SpatialReference; import com.esri.core.geometry.Unit; import com.esri.ges.core.component.ComponentException; import com.esri.ges.core.geoevent.DefaultFieldDefinition; import com.esri.ges.core.geoevent.FieldDefinition; import com.esri.ges.core.geoevent.FieldType; import com.esri.ges.core.geoevent.GeoEvent; import com.esri.ges.core.geoevent.GeoEventDefinition; import com.esri.ges.core.geoevent.GeoEventPropertyName; import com.esri.ges.core.validation.ValidationException; import com.esri.ges.manager.datastore.agsconnection.ArcGISServerConnection; import com.esri.ges.manager.datastore.agsconnection.ArcGISServerType; import com.esri.ges.manager.datastore.agsconnection.Field; import com.esri.ges.manager.datastore.agsconnection.Layer; import com.esri.ges.manager.datastore.agsconnection.ArcGISServerConnectionManager; import com.esri.ges.manager.geoeventdefinition.GeoEventDefinitionManager; import com.esri.ges.messaging.GeoEventCreator; import com.esri.ges.messaging.Messaging; import com.esri.ges.processor.GeoEventProcessorBase; import com.esri.ges.processor.GeoEventProcessorDefinition; public class QueryReportProcessor extends GeoEventProcessorBase { //private enum SortType {Name, Distance}; //public SortType currentSort = SortType.Name; private static final Log LOG = LogFactory.getLog(QueryReportProcessor.class); private Tokenizer tokenizer = new Tokenizer(); private Map<String, String> eventTokenMap = new HashMap<String, String>(); public GeoEventDefinitionManager manager; public ArcGISServerConnectionManager connectionManager; public Messaging messaging; private SpatialReference srIn; private SpatialReference srBuffer; private SpatialReference srOut; private double radius; private String units; private int inwkid; private int outwkid; private int bufferwkid; private String geoSrc; private Boolean useCentroid; private String eventfld; private Boolean useTimeStamp; private String file; private String host; String outDefName; String connName; private ArcGISServerConnection conn; private String folder; private String service; private String lyrName; private Layer layer; private String layerId; private String field; //Field[] fields; private Boolean calcDist; private String wc; private String lyrHeaderCfg; private String distToken=""; private Boolean sortByDist; private String distUnits=""; //String token; private String sortField; private String itemConfig; private String title; private String header; private com.esri.core.geometry.Geometry inGeometry; private GeoEvent currentEvent = null; private String ts; private String time; private String endpoint=null; private String token; public QueryReportProcessor(GeoEventProcessorDefinition definition, GeoEventDefinitionManager m, ArcGISServerConnectionManager cm, Messaging msg) throws ComponentException { super(definition); manager = m; connectionManager = cm; messaging = msg; geoEventMutator= true; } @Override public void shutdown() { // Destruction Phase super.shutdown(); } @Override public boolean isGeoEventMutator() { return true; } @Override public void afterPropertiesSet() { radius = (Double)properties.get("radius").getValue(); units = properties.get("units").getValue().toString(); //inwkid = (Integer) properties.get("wkidin").getValue(); outwkid = (Integer) properties.get("wkidout").getValue(); bufferwkid = (Integer) properties.get("wkidbuffer").getValue(); geoSrc = properties.get("geosrc").getValueAsString(); useCentroid = (Boolean)properties.get("usecentroid").getValue(); eventfld = properties.get("geoeventdef").getValue().toString(); useTimeStamp = (Boolean)properties.get("usetimestamp").getValue(); DateTime dt = DateTime.now(); ts = ((Integer) dt.getYear()).toString() + ((Integer) dt.getMonthOfYear()).toString() + ((Integer) dt.getDayOfMonth()).toString() + ((Integer) dt.getHourOfDay()).toString() + ((Integer) dt.getMinuteOfHour()).toString() + ((Integer) dt.getSecondOfMinute()).toString(); time = ((Integer) dt.getYear()).toString() +"/" + ((Integer) dt.getMonthOfYear()).toString() +"/"+ ((Integer) dt.getDayOfMonth()).toString() +" "+ ((Integer) dt.getHourOfDay()).toString() + ":"+((Integer) dt.getMinuteOfHour()).toString() + ":"+((Integer) dt.getSecondOfMinute()).toString(); file = properties.get("filename").getValueAsString() + ts + ".html"; host = properties.get("host").getValueAsString(); outDefName = properties.get("gedname").getValueAsString(); connName = properties.get("connection").getValueAsString(); folder = properties.get("folder").getValueAsString(); service = properties.get("service").getValueAsString(); lyrName = properties.get("layer").getValueAsString(); try { conn = connectionManager.getArcGISServerConnection(connName); } catch(Exception e) { LOG.error(e.getMessage()); ValidationException ve = new ValidationException("Unable to make connection to ArcGIS Server"); LOG.error(ve.getMessage()); try { throw ve; } catch (ValidationException e1) { e1.printStackTrace(); } } layer =conn.getLayer(folder, service, lyrName, ArcGISServerType.FeatureServer); layerId = ((Integer)layer.getId()).toString(); field = properties.get("field").getValueAsString(); sortField = properties.get("sortfield").getValueAsString(); if(!properties.get("endpoint").getValueAsString().isEmpty()) { endpoint=properties.get("endpoint").getValueAsString(); } try { token = conn.getDecryptedToken(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } //fields = conn.getFields(folder, service, layer.getId(), ArcGISServerType.FeatureServer); calcDist = (Boolean)properties.get("calcDistance").getValue(); wc = properties.get("wc").getValueAsString(); lyrHeaderCfg = properties.get("lyrheader").getValueAsString(); sortByDist=false; if(calcDist) { sortByDist = (Boolean)properties.get("sortdist").getValue(); distToken="${distance.value}"; distUnits=properties.get("dist_units").getValueAsString(); } //token = properties.get("field-token").getValueAsString(); itemConfig = properties.get("item-config").getValueAsString(); title = properties.get("title").getValueAsString(); Object objHeader = properties.get("header"); header = null; if(objHeader != null) { header = properties.get("header").getValueAsString(); } } @Override public synchronized void validate() throws ValidationException { if(radius <= 0) { ValidationException ve = new ValidationException("Radius cannot be less than or equal to 0"); LOG.error(ve.getMessage()); throw ve; } try { srBuffer = SpatialReference.create(bufferwkid); } catch(Exception e) { LOG.error(e.getMessage()); ValidationException ve = new ValidationException("Invalid wkid"); LOG.error(ve.getMessage()); throw ve; } try { srOut = SpatialReference.create(outwkid); } catch(Exception e) { LOG.error(e.getMessage()); ValidationException ve = new ValidationException("Invalid wkid"); LOG.error(ve.getMessage()); throw ve; } } @Override public GeoEvent process(GeoEvent ge) throws Exception { //CreateQueryMap(); if(!ge.getGeoEventDefinition().getTagNames().contains("GEOMETRY")) { return null; } srIn=ge.getGeometry().getSpatialReference(); inwkid = srIn.getID(); currentEvent = ge; List<FieldDefinition> fldDefs = ge.getGeoEventDefinition().getFieldDefinitions(); for(FieldDefinition fd: fldDefs) { if(fd.getType() != FieldType.Geometry && fd.getType() != FieldType.Group) { String n = fd.getName(); String tk = tokenizer.tokenize("geoevent."+n); eventTokenMap.put(tk, n); } } ArrayList<Object> queries = CreateQueries(); MapGeometry geo = ge.getGeometry(); MapGeometry inGeo = null; if(geoSrc.equals("Buffer")) { Geometry rtGeo = constructGeometry(geo); if(useCentroid) { if(geo.getGeometry().getType() == Geometry.Type.Point) { inGeometry = rtGeo; } else { Envelope env = new Envelope(); rtGeo.queryEnvelope(env); inGeometry = env.getCenter(); } } else { inGeometry = constructGeometry(geo); } Unit u = queryUnit(units); inGeo = constructBuffer(geo.getGeometry(),radius,u); } else if(geoSrc.equals("Event_Definition")) { String geostr = (String)ge.getField(eventfld); MapGeometry g = constructGeometryFromString(geostr); Geometry polyGeo= constructGeometry(g); if(useCentroid) { Envelope env = new Envelope(); polyGeo.queryEnvelope(env); inGeometry = env.getCenter(); } else { inGeometry = polyGeo; } com.esri.core.geometry.Geometry projGeo = GeometryEngine.project(polyGeo, srBuffer, srOut); inGeo = new MapGeometry(projGeo, srOut); //String json = GeometryEngine.geometryToJson(srOut, projGeo); } else { Geometry polyGeo = constructGeometry(geo); if(useCentroid) { Envelope env = new Envelope(); polyGeo.queryEnvelope(env); inGeometry = env.getCenter(); } else { inGeometry = polyGeo; } com.esri.core.geometry.Geometry projGeo = GeometryEngine.project(polyGeo, srBuffer, srOut); //String json = GeometryEngine.geometryToJson(srOut, projGeo); inGeo = new MapGeometry(projGeo, srOut); } Geometry newGeo = inGeo.getGeometry(); String jsonGeo = GeometryEngine.geometryToJson(srOut.getID(), newGeo); String geotype = GeometryUtility.parseGeometryType(newGeo.getType()); HashMap<String, Object> responseMap = ExecuteRestQueries(jsonGeo, geotype, queries); String timestamp = ""; if(useTimeStamp) { timestamp = time; } ParseResponses(timestamp, file, responseMap); if(host.contains("http://")) { host.replace("http://", ""); } if (host.contains(":6180")) { host.replace(":6180", ""); } String url = "http://" + host + ":6180/geoevent/assets/reports/" + file; GeoEventDefinition geoDef = ge.getGeoEventDefinition(); GeoEventDefinition edOut; if((edOut=manager.searchGeoEventDefinition(outDefName, getId()))==null) { List<FieldDefinition> fds = Arrays .asList(((FieldDefinition) new DefaultFieldDefinition( "url", FieldType.String))); edOut = geoDef.augment(fds); edOut.setOwner(getId()); edOut.setName(outDefName); manager.addGeoEventDefinition(edOut); } GeoEventCreator geoEventCreator = messaging.createGeoEventCreator(); GeoEvent geOut = geoEventCreator.create(edOut.getGuid(), new Object[] { ge.getAllFields(), url }); geOut.setProperty(GeoEventPropertyName.TYPE, "message"); geOut.setProperty(GeoEventPropertyName.OWNER_ID, getId()); geOut.setProperty(GeoEventPropertyName.OWNER_ID, definition.getUri()); for (Map.Entry<GeoEventPropertyName, Object> property : ge.getProperties()) if (!geOut.hasProperty(property.getKey())) geOut.setProperty(property.getKey(), property.getValue()); //queries.clear(); //responseMap.clear(); return geOut; } private Unit queryUnit(String units) { UnitConverter uc = new UnitConverter(); String cn = uc.findConnonicalName(units); int unitout = uc.findWkid(cn); Unit u = LinearUnit.create(unitout); return u; } private Geometry constructGeometry(MapGeometry geo) throws Exception { try{ Geometry geoIn= geo.getGeometry(); return GeometryEngine.project(geoIn, srIn, srBuffer); } catch(Exception e) { LOG.error(e.getMessage()); LOG.error(e.getStackTrace()); throw(e); } } private MapGeometry constructGeometryFromString(String geoString) { String[] pairs = geoString.split(" "); Polygon polygon = new Polygon(); Boolean firstit = true; for(String coords: pairs) { String[] tuple = coords.split(","); Double x = Double.parseDouble(tuple[0]); Double y = Double.parseDouble(tuple[1]); Point p = new Point(x,y); Double z = Double.NaN; if (tuple.length>2) { z = Double.parseDouble(tuple[2]); p.setZ(z); } if(firstit) { polygon.startPath(p); firstit=false; } else { polygon.lineTo(p); } } polygon.closeAllPaths(); MapGeometry mapgeo = new MapGeometry(polygon, srOut); return mapgeo; } private MapGeometry constructBuffer(Geometry geo, double radius, Unit u) throws JsonParseException, IOException { Polygon buffer = GeometryEngine.buffer(inGeometry, srBuffer, radius, u); Geometry bufferout = GeometryEngine.project(buffer, srBuffer, srOut); MapGeometry mapGeo = new MapGeometry(bufferout, srOut); return mapGeo; //String json = GeometryEngine.geometryToJson(srOut, bufferout); //return spatial.fromJson(json); } public ArrayList<Object> CreateQueries() { ArrayList<Object>queries = new ArrayList<Object>(); URL url = conn.getUrl(); String curPath=null; if (endpoint != null) { curPath = endpoint; } else { String baseUrl = url.getProtocol() +"://"+ url.getHost() + ":" + url.getPort() + url.getPath() + "rest/services/"; curPath = baseUrl + "/" + folder + "/" + service + "/FeatureServer/" + layerId; } String restpath = curPath + "/query?"; HashMap<String, Object> query = new HashMap<String, Object>(); HashMap<String, String> fieldMap = new HashMap<String, String>(); String fldsString = field; String[] fieldArray = fldsString.split(","); for(String f: fieldArray) { String tk = tokenizer.tokenize(f); fieldMap.put(f, tk); } query.put("restpath", restpath); query.put("path", curPath); query.put("whereclause", wc); query.put("fields", fldsString ); //query.put("outfields", fields); query.put("tokenMap", fieldMap); query.put("headerconfig", lyrHeaderCfg); query.put("usingdist", calcDist); query.put("sortbydist", sortByDist); query.put("distunits", distUnits); query.put("disttoken", distToken); query.put("itemconfig", itemConfig); query.put("layer", layer.getName()); UUID uid = UUID.randomUUID(); query.put("id", uid); queries.add(query); return queries; } private HashMap<String, Object> ExecuteRestQueries(String jsonGeometry, String geoType, ArrayList<Object> queries) throws UnsupportedEncodingException { String contentType = "application/json"; HttpClient httpclient = HttpClientBuilder.create().build(); HashMap<String, Object>responseMap = new HashMap<String, Object>(); for (int i = 0; i < queries.size(); ++i) { @SuppressWarnings("unchecked") HashMap<String, Object> query = (HashMap<String, Object>) queries .get(i); String path = (String) query.get("restpath"); String wc = URLEncoder.encode((String) query.get("whereclause"), "UTF-8"); String geo = URLEncoder.encode(jsonGeometry, "UTF-8"); String fields = (String) query.get("fields"); @SuppressWarnings("unchecked") HashMap<String, String> tokenMap = (HashMap<String, String>) query .get("tokenMap"); String itemConfig = (String) query.get("itemconfig"); // String args = "where=" + wc + "&objectIds=&time=&geometry=" + geo + "&geometryType=" + geoType + "&inSR=&spatialRel=esriSpatialRelIntersects&relationParam=&outFields=*" //+ fields + "&returnGeometry=true&maxAllowableOffset=&geometryPrecision=&outSR=&gdbVersion=&returnDistinctValues=false&returnIdsOnly=false&returnCountOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&f=json"; if(token != null) { args += "&token=" + token; } String uri = path + args; try { HttpPost httppost = new HttpPost(uri); httppost.setHeader("Accept", contentType); HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); if (entity != null) { InputStream instream = entity.getContent(); try { // instream.read(); BufferedReader br = new BufferedReader( new InputStreamReader((instream))); String output = ""; String ln; while ((ln = br.readLine()) != null) { output += ln; } //JsonFactory jf = new JsonFactory(); //JsonParser jp = jf.createJsonParser(output); //FeatureSet fset = FeatureSet.fromJson(jp); Map<String, Object> map = new HashMap<String, Object>(); ObjectMapper mapper = new ObjectMapper(); map = mapper.readValue(output, new TypeReference<HashMap<String, Object>>(){}); HashMap<String, Object> tuple = new HashMap<String, Object>(); String lyr = (String)query.get("layer"); String lyrheadercfg = (String)query.get("headerconfig"); Boolean calcdist = (Boolean)query.get("usingdist"); Boolean sortByDist = (Boolean)query.get("sortbydist"); String distToken = (String)query.get("disttoken"); String distUnits = (String)query.get("distunits"); String id = query.get("id").toString(); tuple.put("fset", map); tuple.put("tokenmap", tokenMap); tuple.put("config", itemConfig); tuple.put("layer", lyr); tuple.put("lyrheader", lyrheadercfg); tuple.put("sortbydist", sortByDist); tuple.put("calcdist", calcdist); tuple.put("distunits", distUnits); tuple.put("disttoken", distToken); responseMap.put(id, tuple); } catch (IOException ex) { // In case of an IOException the connection will be // released // back to the connection manager automatically LOG.error(ex); throw ex; } catch (RuntimeException ex) { // In case of an unexpected exception you may want to // abort // the HTTP request in order to shut down the underlying // connection immediately. LOG.error(ex); httppost.abort(); throw ex; }catch(Exception ex){ LOG.error(ex); httppost.abort(); throw ex; } finally { // Closing the input stream will trigger connection // release try { instream.close(); } catch (Exception ignore) { } } } } catch (Exception ex) { LOG.error(ex); ex.printStackTrace(); } } return responseMap; } private Geometry generateGeoFromMap(Map<String, Object> objGeo) { Geometry geo = null; if(objGeo.containsKey("rings")) { ArrayList<ArrayList<ArrayList<String>>> rings= (ArrayList<ArrayList<ArrayList<String>>>)objGeo.get("rings"); geo = generatePolygon(rings); } else if(objGeo.containsKey("paths")) { ArrayList<ArrayList<ArrayList<String>>> paths= (ArrayList<ArrayList<ArrayList<String>>>)objGeo.get("paths"); geo = generatePolyLine(paths); } else if(objGeo.containsKey("points")) { } else { Double x = Double.valueOf(objGeo.get("x").toString()); Double y = Double.valueOf(objGeo.get("y").toString()); if(objGeo.size() > 2) { Double z = Double.valueOf(objGeo.get("z").toString()); geo = generate3DPoint(x,y,z); } else { geo = generatePoint(x,y); } } return geo; } private Point generatePoint(Double x, Double y) { Point p = new Point(x, y); return p; } private Point generate3DPoint(Double x, Double y, Double z) { Point p = new Point(x, y, z); return p; } private Polyline generatePolyLine(ArrayList<ArrayList<ArrayList<String>>> paths) { Polyline polyln = new Polyline(); for(ArrayList<ArrayList<String>> path: paths) { Boolean firstPt = true; for(ArrayList<String> strPt: path) { Point p = null; if(strPt.size() > 2) { Double x = Double.valueOf(strPt.get(0)); Double y = Double.valueOf(strPt.get(1)); Double z = Double.valueOf(strPt.get(2)); p = generate3DPoint(x,y,z); } else { Double x = Double.valueOf(strPt.get(0)); Double y = Double.valueOf(strPt.get(1)); p = generatePoint(x,y); } if(firstPt) { polyln.startPath(p); firstPt = false; } else { polyln.lineTo(p); } } } return polyln; } private Polygon generatePolygon(ArrayList<ArrayList<ArrayList<String>>> paths) { Polygon polygon = new Polygon(); for(ArrayList<ArrayList<String>> path: paths) { Boolean firstPt = true; for(ArrayList<String> strPt: path) { Point p = null; if(strPt.size() > 2) { Double x = Double.valueOf(strPt.get(0)); Double y = Double.valueOf(strPt.get(1)); Double z = Double.valueOf(strPt.get(2)); p = generate3DPoint(x,y,z); } else { Double x = Double.valueOf(strPt.get(0)); Double y = Double.valueOf(strPt.get(1)); p = generatePoint(x,y); } if(firstPt) { polygon.startPath(p); firstPt = false; } else { polygon.lineTo(p); } } } polygon.closeAllPaths(); return polygon; } private String GetDistAsString(Map<String, Object> objGeo, SpatialReference inputSr, String units) throws JsonParseException, IOException { Geometry geo = generateGeoFromMap(objGeo); com.esri.core.geometry.Geometry curGeo; if(!inputSr.equals(srBuffer)) { curGeo = GeometryEngine.project(geo, inputSr, srBuffer); } else { curGeo=geo; } double tmpDist = GeometryEngine.distance(inGeometry, curGeo, srBuffer); UnitConverter uc = new UnitConverter(); int inUnitWkid = uc.findWkid(srBuffer.getUnit().getName()); String cn = uc.findConnonicalName(units); int outUnitWkid = uc.findWkid(cn); double dist; if(inUnitWkid!=outUnitWkid) { dist = uc.Convert(tmpDist, inUnitWkid, outUnitWkid); } else { dist=tmpDist; } DecimalFormat df = new DecimalFormat("#.00"); return df.format(dist); } private void ParseResponses(String timestamp, String file, HashMap<String, Object>responseMap) throws JsonParseException, IOException { Map<String, List<String>> nameSortMap = new HashMap<String, List<String>>(); Map<Double, List<String>> distSortMap = new HashMap<Double, List<String>>(); ArrayList<String> nSortList = new ArrayList<String>(); ArrayList<Double> dSortList = new ArrayList<Double>(); Set<String> keys = responseMap.keySet(); Iterator<String> it = keys.iterator(); String body = ""; while(it.hasNext()) { String k = it.next(); @SuppressWarnings("unchecked") HashMap<String, Object> response = (HashMap<String, Object>) responseMap.get(k); @SuppressWarnings("unchecked") Map<String, Object> fset = (HashMap<String,Object>)response.get("fset"); String cfg = (String)response.get("config"); @SuppressWarnings("unchecked") HashMap<String,Object>tokenmap=(HashMap<String, Object>)response.get("tokenmap"); String layer = (String)response.get("layer"); //String featuresAsString = fset.get("features").toString(); List<HashMap<String, Object>> features = (ArrayList<HashMap<String, Object>>)fset.get("features"); ObjectMapper om = new ObjectMapper(); //List<Object> features = new ArrayList<Object>(); //Graphic[] features = fset.getGraphics(); //List<String> features = om.readValue(featuresAsString, TypeFactory.defaultInstance().constructCollectionType(List.class, String.class)); String lyrHeader = (String)response.get("lyrheader"); if(!lyrHeader.isEmpty()) { lyrHeader = "<b>"+lyrHeader+"</b>"; } String items = ""; items += "<b>"+layer.toUpperCase() + ": </b>"; Boolean usingDist = (Boolean)response.get("calcdist"); Boolean sortByDist = (Boolean)response.get("sortbydist"); String distUnits = (String)response.get("distunits"); String distToken = (String)response.get("disttoken"); Map<String, Object> srmap = (HashMap<String, Object>)fset.get("spatialReference");; Integer wkid = (Integer)srmap.get("wkid"); //SpatialReference fsetSr = fset.getSpatialReference(); SpatialReference fsetSr = SpatialReference.create(wkid); for (int i=0; i<features.size();++i) { HashMap<String, Object> f = features.get(i); Map<String, Object> att = (Map<String, Object>) f.get("attributes"); Map<String, Object> objGeo = (Map<String, Object>)f.get("geometry"); //String geoString = f.get("geometry").toString(); Set<String> fields = tokenmap.keySet(); Iterator<String> itFields = fields.iterator(); String item = cfg; Double distVal = null; if(usingDist) { String d = this.GetDistAsString(objGeo, fsetSr, distUnits); if(sortByDist) { distVal = Double.valueOf(d); } item = item.replace(distToken, d); } String attVal=null; String sortAttVal=null; while(itFields.hasNext()) { String fldname = itFields.next(); String token = (String) tokenmap.get(fldname); attVal = att.get(fldname).toString(); if(!sortByDist) { if(fldname.equals(sortField)) { sortAttVal = attVal; } } item = item.replace(token, attVal); } if(!sortByDist) { if(!nameSortMap.containsKey(sortAttVal)) { List<String> l = new ArrayList<String>(); l.add(item); nameSortMap.put(sortAttVal, l); nSortList.add(sortAttVal); } else { List<String> l = nameSortMap.get(sortAttVal); l.add(item); Collections.sort(l); } } else { if(!distSortMap.containsKey(distVal)) { List<String> l = new ArrayList<String>(); l.add(item); distSortMap.put(distVal, l); dSortList.add(distVal); } else { List<String> l = distSortMap.get(distVal); l.add(item); Collections.sort(l); } } } String sortedItems = ""; if(!sortByDist) { Collections.sort(nSortList); sortedItems = ConstructSortedItemsByName(nameSortMap, nSortList); } else { Collections.sort(dSortList); sortedItems = ConstructSortedItemsByDistance(distSortMap, dSortList); } //String sortedItems = ConstructSortedItems(sortByDist); items = sortedItems; body += lyrHeader+"<br>"+items; } String content = ""; //File file = new File("C:/Dev/Java/DefenseSolution/defense-geometry-processor/src/main/resources/ReportTemplate.html"); //for ex foo.txt try { //String name = this.getClass().getName(); InputStream is = this.getClass().getClassLoader().getResourceAsStream("ReportTemplate.html"); //FileInputStream is = new FileInputStream(file); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String ln; while ((ln = br.readLine()) != null) { content += ln; } if(!timestamp.isEmpty()) { String tsToken = "${timestamp.value}"; title = title.replace(tsToken, timestamp); if(header != null) { header = header.replace(tsToken, timestamp); } body = body.replace(tsToken, timestamp); } content = content.replace("${TITLE}", "<h1>" +title+"</h1>"); content = content.replace("${HEADING}", "<h2>" +header+"</h2>"); content = content.replace("${BODY}", body); br.close(); Set<String> eventTokens = eventTokenMap.keySet(); Iterator<String> eventIt = eventTokens.iterator(); while(eventIt.hasNext()) { String et = eventIt.next(); String fn = eventTokenMap.get(et); String val = currentEvent.getField(fn).toString(); content = content.replace(et, val); } File dir = new File("assets/reports"); if(!dir.exists()) { dir.mkdir(); } String filename = "assets/reports/" + file; File outfile = new File(filename); FileOutputStream fos = new FileOutputStream(outfile); OutputStreamWriter osw = new OutputStreamWriter(fos); Writer w = new BufferedWriter(osw); w.write(content); w.close(); } catch (IOException e) { e.printStackTrace(); } } private String ConstructSortedItemsByName( Map<String, List<String>> nameSortMap, ArrayList<String> nSortList) { String items = ""; Boolean first = true; for (String n : nSortList) { List<String> l = nameSortMap.get(n); for (String item : l) { if (first) { items += item; first = false; } else { items += "<br>" + item; } } } return items; } private String ConstructSortedItemsByDistance( Map<Double, List<String>> distSortMap, ArrayList<Double> dSortList) { String items = ""; Boolean first = true; for (Double d : dSortList) { List<String> l = distSortMap.get(d); for (String item : l) { if (first) { items += item; first = false; } else { items += "<br>" + item; } } } return items; } }