package com.smtaiserver.smtaiserver.control; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.springframework.web.servlet.ModelAndView; import com.smtservlet.util.Json; import com.smtaiserver.smtaiserver.core.SMTAIServerApp; import com.smtaiserver.smtaiserver.core.SMTAIServerRequest; import com.smtaiserver.smtaiserver.database.SMTDatabase; import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecord; import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecords; import com.smtaiserver.smtaiserver.gismap.SMTGisMapLayerDef; import com.smtaiserver.smtaiserver.gismap.SMTMapOtypeDef; import com.smtaiserver.smtaiserver.gismap.SMTMapVPropDef; import com.smtaiserver.smtaiserver.gismap.tabledef.SMTMapTableDef; import com.smtaiserver.smtaiserver.gismap.theme.SMTMapThemeDef; import com.smtaiserver.smtaiserver.javaai.ast.ASTDBMap; import com.smtservlet.core.SMTRequest; import com.smtservlet.util.SMTJsonWriter; import com.smtservlet.util.SMTStatic; public class SMTAIMapControl { private static class VPROPFilter { public SMTMapVPropDef _vpropDef; public Json _jsonCondtion; public VPROPFilter(SMTMapVPropDef vpropDef, Json jsonCondtion) { _vpropDef = vpropDef; _jsonCondtion = jsonCondtion; } } public ModelAndView getVectorTile(SMTAIServerRequest tranReq) throws Exception { int x = tranReq.convParamToInteger("x", true); int y = tranReq.convParamToInteger("y", true); int z = tranReq.convParamToInteger("z", true); String layerId = tranReq.convParamToString("layer_id", true); //System.out.println(String.format("==========>layer=%s z=%d x=%d y=%d", layerId, z, x, y)); SMTGisMapLayerDef mapLayerDef = SMTAIServerApp.getApp().getMapLayerDef(layerId); return mapLayerDef.queryVectorTileToResponse(tranReq, z, x, y); } public ModelAndView getMapLayers(SMTRequest tranReq) throws Exception { Map map = SMTAIServerApp.getApp().getMapLayerDefMap(); SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null); jsonWr.beginArray("layers"); for(SMTGisMapLayerDef layerDef : map.values()) { jsonWr.beginMap(null); { jsonWr.addKeyValue("id", layerDef.getLayerId()); jsonWr.addKeyValue("title", layerDef.getTitle()); jsonWr.addKeyValue("group", layerDef.getGroupName()); jsonWr.addKeyValue("icon", layerDef.getIcon()); jsonWr.addKeyValue("min_ratio", layerDef.getMinRatio()); jsonWr.addKeyValue("max_ratio", layerDef.getMaxRatio()); } jsonWr.endMap(); } jsonWr.endArray(); return tranReq.returnJson(jsonWr); } public ModelAndView getMapVProps(SMTRequest tranReq) throws Exception { Map mapOTYPE2Def = SMTAIServerApp.getApp().getMapVPropDefMap(); SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null); jsonWr.beginMap("otypes"); for(SMTMapOtypeDef otypeDef : mapOTYPE2Def.values()) { jsonWr.beginMap(otypeDef.getOTYPE()); { jsonWr.addKeyValue("title", otypeDef.getTitle()); jsonWr.beginMap("vprops"); for(SMTMapVPropDef vpropDef : otypeDef.getVPropDefMap().values()) { jsonWr.beginMap(vpropDef.getVPROP()); { jsonWr.addKeyValue("title", vpropDef.getTitle()); jsonWr.addKeyValue("unit", vpropDef.getUnit()); } jsonWr.endMap(); } jsonWr.endMap(); } jsonWr.endMap(); } jsonWr.endMap(); return tranReq.returnJson(jsonWr); } public ModelAndView getMapVPropValues(SMTRequest tranReq) throws Exception { String OTYPE = tranReq.convParamToString("otype", true); String ONAME = tranReq.convParamToString("oname", true); String[] VPROPS = tranReq.convParamToStringArray("vprops", true); Date time = tranReq.convParamToDate("time", true); Map> mapOTYPE2VPROP2Def = new HashMap<>(); // 扫描属性,按照TABLE进行分类 for(String VPROP : VPROPS) { SMTMapVPropDef vpropDef = SMTAIServerApp.getApp().getMapVPropDefMap(OTYPE, VPROP); SMTMapTableDef tableDef = vpropDef.getTableDef(); List listVPROPDef = mapOTYPE2VPROP2Def.get(tableDef); if(listVPROPDef == null) { listVPROPDef = new ArrayList<>(); mapOTYPE2VPROP2Def.put(tableDef, listVPROPDef); } listVPROPDef.add(vpropDef); } // 按照TABLE查询数据 try(ASTDBMap dbMap = new ASTDBMap()) { SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null); jsonWr.beginMap("values"); for(Entry> entryTABLEDef : mapOTYPE2VPROP2Def.entrySet()) { SMTMapTableDef tabelDef = entryTABLEDef.getKey(); // 生成查询SQL StringBuilder sbSQL = new StringBuilder(); sbSQL.append("SELECT ONAME\n"); for(SMTMapVPropDef vpropDef : entryTABLEDef.getValue()) { sbSQL.append("," + vpropDef.getColumnSql() + " AS " + vpropDef.getVPROP() + "\n"); } sbSQL.append("FROM \n"); tabelDef.createOnlyTimeSQL(time, sbSQL); sbSQL.append("\n"); sbSQL.append("WHERE OTYPE=? AND ONAME=?"); // 执行查询 DBRecords recs = dbMap.getDatabase(tabelDef.getDataSourceId()) .querySQL(sbSQL.toString(), new Object[] {OTYPE, ONAME}); if(recs.getRowCount() > 0) { DBRecord rec = recs.getRecord(0); for(SMTMapVPropDef vpropDef : entryTABLEDef.getValue()) { String VPROP = vpropDef.getVPROP(); jsonWr.addKeyValue(VPROP, rec.getString(VPROP)); } } } jsonWr.endMap(); return tranReq.returnJson(jsonWr); } } public ModelAndView getMapDrawStyles(SMTRequest tranReq) throws Exception { SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null); try(SMTDatabase db = SMTAIServerApp.getApp().allocDatabase()) { DBRecords recs = db.querySQL("SELECT * FROM ai_map.map_style_def", null); jsonWr.beginArray("values"); for(DBRecord rec : recs.getRecords()) { jsonWr.beginMap(null); { jsonWr.addKeyValue("id", rec.getString("style_id")); jsonWr.addKeyValue("type", rec.getString("style_type")); String sStyleConfig = rec.getString("style_config"); if(!SMTStatic.isNullOrEmpty(sStyleConfig)) jsonWr.addKeyRaw("config", sStyleConfig); } jsonWr.endMap(); } jsonWr.endArray(); } return tranReq.returnJson(jsonWr); } public ModelAndView getMapVPropViewConfig(SMTRequest tranReq) throws Exception { SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null); try(SMTDatabase db = SMTAIServerApp.getApp().allocDatabase()) { DBRecords recs = db.querySQL("SELECT otype, vprop_view_json FROM ai_map.map_otype_def WHERE vprop_view_json IS NOT NULL", null); jsonWr.beginMap("values"); for(DBRecord rec : recs.getRecords()) { jsonWr.addKeyRaw(rec.getString("otype"), rec.getString("vprop_view_json")); } jsonWr.endMap(); } return tranReq.returnJson(jsonWr); } public ModelAndView getMapThemeList(SMTRequest tranReq) throws Exception { SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null); jsonWr.beginArray("values"); for(SMTMapThemeDef themeDef : SMTAIServerApp.getApp().getMapThemeDefMap().values()) { jsonWr.beginMap(null); { jsonWr.addKeyValue("id", themeDef.getId()); jsonWr.addKeyValue("group", themeDef.getGroup()); jsonWr.addKeyValue("title", themeDef.getTitle()); } jsonWr.endMap(); } jsonWr.endArray(); return tranReq.returnJson(jsonWr); } public ModelAndView getMapLayerGroupList(SMTRequest tranReq) throws Exception { SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null); try(SMTDatabase db = SMTAIServerApp.getApp().allocDatabase()) { DBRecords recs = db.querySQL("SELECT layer_id, layer_group FROM ai_map.map_layer_def ORDER BY layer_group_order", null); jsonWr.beginArray("values"); for(DBRecord rec : recs.getRecords()) { jsonWr.beginMap(null); { jsonWr.addKeyValue("layer_id", rec.getString("layer_id")); jsonWr.addKeyValue("group", rec.getString("layer_group")); } jsonWr.endMap(); } jsonWr.endArray(); } return tranReq.returnJson(jsonWr); } // "junction_elevation" public ModelAndView switchMapTheme(SMTRequest tranReq) throws Exception { String[] themeIdList = tranReq.convParamToStringArray("theme_id", true); Date curTime = tranReq.convParamToDate("time", true); // 获取参数 SMTMapThemeDef.SMTMapThemeStyleMap themeStyleMap = new SMTMapThemeDef.SMTMapThemeStyleMap(); // 生成并合并style SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null); try(ASTDBMap dbMap = new ASTDBMap()) { for(String themeId : themeIdList) { SMTMapThemeDef themeDef = SMTAIServerApp.getApp().getMapThemeDef(themeId); themeDef.queryThemeStyles(dbMap, curTime, themeStyleMap); themeDef.legendToJson(jsonWr); } } // 将结果输出成json themeStyleMap.styleToJson(jsonWr); return tranReq.returnJson(jsonWr); } public ModelAndView searchMapElemet(SMTRequest tranReq) throws Exception { String searchText = tranReq.convParamToString("search_text", true); int maxCount = tranReq.convParamToInteger("max_count", true); Date time = tranReq.convParamToDate("time", true); SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null); int[] count = new int[] {0, maxCount}; try(SMTDatabase db = SMTAIServerApp.getApp().allocDatabase()) { jsonWr.beginArray("values"); for(SMTGisMapLayerDef mapLayerDef : SMTAIServerApp.getApp().getMapLayerDefMap().values()) { mapLayerDef.searchElement(db, time, searchText, count, jsonWr); if(count[0] >= count[1]) break; } jsonWr.endArray(); } return tranReq.returnJson(jsonWr); } // {"name":"extent", "title":"搜索地理范围[minx,miny,maxx,maxy]", "required":false}, // {"name":"max_count", "title":"最大个数", "required":true}, // {"name":"time", "title":"要查询的时间", "required":true}, // {"name":"otype", "title":"要查询的otype", "required":true}, // {"name":"condtions", "title":"要查询的条件[{vprop:属性名,operator:操作(eq,ne,gt,gte,lt,lte,contains),value:查询值}]", "required":true} public ModelAndView advanceSearchMapElemet(SMTRequest tranReq) throws Exception { double[] bounds = tranReq.convParamToDoubleArray("extent", false); int maxCount = tranReq.convParamToInteger("max_count", true); Date time = tranReq.convParamToDate("time", true); String otype = tranReq.convParamToString("otype", true); Json jsonConditions = tranReq.convParamToJson("condtions", true); SMTMapOtypeDef otypeDef = SMTAIServerApp.getApp().getMapOTypeDef(otype); SMTJsonWriter jsonWr = tranReq.newReturnJsonWriter(true, null, null); // 将属性按照表定义分组 Map> mapTableDef2VpropDef = new HashMap<>(); for(Json jsonCondition : jsonConditions.asJsonList()) { String vprop = jsonCondition.getJson("vprop").asString(); SMTMapVPropDef vpropDef = otypeDef.getVPropDef(vprop); SMTMapTableDef tableDef = vpropDef.getTableDef(); Set setVpropDef = mapTableDef2VpropDef.get(tableDef); if(setVpropDef == null) { setVpropDef = new HashSet<>(); mapTableDef2VpropDef.put(tableDef, setVpropDef); } setVpropDef.add(new VPROPFilter(vpropDef, jsonCondition)); } // 根据属性表获取数据 int curCount = 0; jsonWr.beginArray("values"); try(ASTDBMap dbMap = new ASTDBMap()) { for(Entry> entryTableDef : mapTableDef2VpropDef.entrySet()) { if(curCount >= maxCount) break; // 生成SQL字段语句 SMTMapTableDef tableDef = entryTableDef.getKey(); Set setVPropDef = entryTableDef.getValue(); StringBuilder sbSQL = new StringBuilder(); sbSQL.append("SELECT OTYPE,ONAME,st_asewkt(ST_Transform(SHAPE, 3857)) AS WKT\n"); for(VPROPFilter vpropFilter : setVPropDef) { sbSQL.append("," + vpropFilter._vpropDef.getColumnSql() + " AS " + vpropFilter._vpropDef.getVPROP() + "\n"); } // 生成SQL的FROM语句 sbSQL.append("\nFROM\n"); tableDef.createOnlyTimeSQL(time, sbSQL); // 生成SQL的条件语句 sbSQL.append("\nWHERE 1=1\n"); if(bounds != null) { // 边界矩形坐标信息: // x0=0, y0=1, x1=2, y1=3 // x0 y0, x0 y1, x1 y1, x1 y0, x0 y0 // 0 1 0 3 2 3 2 1 0 1 sbSQL.append(String.format( " AND ST_Intersects(ST_GeomFromText('POLYGON ( (%s %s, %s %s, %s %s , %s %s, %s %s))') , ST_Transform(shape, 3857))", SMTStatic.toString(bounds[0]), SMTStatic.toString(bounds[1]), SMTStatic.toString(bounds[0]), SMTStatic.toString(bounds[3]), SMTStatic.toString(bounds[2]), SMTStatic.toString(bounds[3]), SMTStatic.toString(bounds[2]), SMTStatic.toString(bounds[1]), SMTStatic.toString(bounds[0]), SMTStatic.toString(bounds[1]) )); } for(VPROPFilter vpropFilter : setVPropDef) { sbSQL.append(" AND " + vpropFilter._vpropDef.getColumnSql() + " "); String op = vpropFilter._jsonCondtion.getJson("operate").asString(); String value = "'" + vpropFilter._jsonCondtion.getJson("value").asString().replace("'", "''") + "'"; if("eq".equals(op)) { sbSQL.append("=" + value); } else if("ne".equals(op)) { sbSQL.append("<>" + value); } else if("gt".equals(op)) { sbSQL.append(">" + value); } else if("gte".equals(op)) { sbSQL.append(">=" + value); } else if("lt".equals(op)) { sbSQL.append("<" + value); } else if("lte".equals(op)) { sbSQL.append("<=" + value); } else if("contains".equals(op)) { sbSQL.append("LIKE" + "'%" + vpropFilter._jsonCondtion.getJson("value").asString().replace("'", "''") + "%'"); } else { throw new Exception("unknow op : " + op); } } sbSQL.append("\nLIMIT " + (maxCount - curCount) + "\n"); // 查询结果集 SMTDatabase db = dbMap.getDatabase(tableDef.getDataSourceId()); DBRecords recs = db.querySQL(sbSQL.toString(), null); curCount += recs.getRowCount(); // 输出结果集 for(DBRecord rec : recs.getRecords()) { jsonWr.beginMap(null); for(Entry entry : rec.getFieldMap().entrySet()) { jsonWr.addKeyValue(entry.getKey(), rec.getString(entry.getValue())); } jsonWr.endMap(); } } } jsonWr.endArray(); return tranReq.returnJson(jsonWr); } }