package com.smtaiserver.smtaiserver.gismap.theme; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.smtaiserver.smtaiserver.core.SMTAIServerApp; import com.smtaiserver.smtaiserver.database.SMTDatabase; import com.smtaiserver.smtaiserver.database.SMTDatabase.DBQueryNotify; import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecord; import com.smtaiserver.smtaiserver.gismap.theme.SMTMapThemeTableDef.SMTMapThemeColumn; import com.smtaiserver.smtaiserver.javaai.ast.ASTDBMap; import com.smtservlet.util.Json; import com.smtservlet.util.SMTJsonWriter; import com.smtservlet.util.SMTStatic; public abstract class SMTMapThemeDef { public enum SMTMapThemeStyleID { PSTYLE, PSIZE, PCOLOR, LSTYLE, LSIZE, LCOLOR, TSTRING, TSIZE, TCOLOR } public static class SMTMapThemeLegendValue { public String _value; public String _style; public SMTMapThemeLegendValue(SMTMapThemeColumn columnDef, String styleName, Json jsonValue) { _value = columnDef.convValueToSQL(jsonValue.getJson("value").asString()); _style = SMTMapThemeDef.convStyleLegendStyle(styleName, jsonValue.getJson("style").asString()); } } public static class SMTMapThemeLegendStyle { public SMTMapThemeColumn _columnDef; public String _default; public String _title; public List _listLegendValue = new ArrayList<>(); public SMTMapThemeLegendStyle(String styleName, SMTMapThemeTableDef tableDef, Json jsonLegend) throws Exception { _columnDef = tableDef.getColumnDef(jsonLegend.getJson("column").asString()); _title = jsonLegend.safeGetStr("title", null); _default = SMTMapThemeDef.convStyleLegendStyle(styleName, jsonLegend.getJson("default").asString()); for(Json jsonLegendValue : jsonLegend.getJson("legends").asJsonList()) { _listLegendValue.add(new SMTMapThemeLegendValue(_columnDef, styleName, jsonLegendValue)); } } public void appendToSQL(StringBuilder sbSQL) { // 如果没有分级,则直接使用缺省值 if(_listLegendValue.size() == 0) { sbSQL.append(_default); } // 生成分级SQL else { sbSQL.append("CASE\n"); for(SMTMapThemeLegendValue legendValue : _listLegendValue) { sbSQL.append("WHEN " + _columnDef._name + " " + _columnDef._op + " " + legendValue._value + " THEN " + legendValue._style + "\n"); } sbSQL.append("ELSE " + _default + " END"); } } } private static class SMTMapThemeStyleDef { public SMTMapThemeTableDef _tableDef; public Map _mapStyle2Legend = new HashMap<>(); private static Logger _logger = LogManager.getLogger(SMTMapThemeStyleDef.class); public SMTMapThemeStyleDef(Json jsonConfig) throws Exception { _tableDef = SMTAIServerApp.getApp().getMapThemeTableDef(jsonConfig.getJson("theme_table").asString()); for(Entry entry : jsonConfig.getJson("styles").asJsonMap().entrySet()) { SMTMapThemeLegendStyle legendStyle = new SMTMapThemeLegendStyle(entry.getKey(), _tableDef, entry.getValue()); _mapStyle2Legend.put(entry.getKey(), legendStyle); } } public void queryThemeStyles(ASTDBMap dbMap, Date curTime, SMTMapThemeStyleMap themeStyleMap) throws Exception { // 生成SQL语句 StringBuilder sbSQL = new StringBuilder(); sbSQL.append("SELECT OTYPE, ONAME\n"); for(Entry entry : _mapStyle2Legend.entrySet()) { sbSQL.append(","); SMTMapThemeLegendStyle legendStyle = entry.getValue(); legendStyle.appendToSQL(sbSQL); sbSQL.append(" AS " + entry.getKey() + "\n"); } sbSQL.append("FROM (\n"); Map mapArgValues = new HashMap<>(); mapArgValues.put("cur_time", curTime); _tableDef.appendToSQL(mapArgValues, sbSQL); sbSQL.append(") T"); // 执行SQL,并将结果导入themeStyleMap SMTDatabase db = dbMap.getDatabase(_tableDef.getDSId()); _logger.info(sbSQL.toString()); db.querySQLNotify(sbSQL.toString(), null, new DBQueryNotify() { @Override public boolean onNextRecord(DBRecord rec) throws Exception { themeStyleMap.appendStyle(rec); return true; } }); } } public static class SMTMapThemeStyleMap { private static class SMTMapThemeStyleCache { public Object[] _styles; public int _pos; public SMTMapThemeStyleCache(Object[] styles, int pos) { _styles = styles; _pos = pos; } } private Map> _mapOTYPE2ONAME2Style = new HashMap<>(); public void appendStyle(DBRecord rec) throws Exception { String OTYPE = rec.getString("OTYPE"); String ONAME = rec.getString("ONAME"); // 获取或创建OTYPE Map mapONAME2Style = _mapOTYPE2ONAME2Style.get(OTYPE); if(mapONAME2Style == null) { mapONAME2Style = new HashMap<>(); _mapOTYPE2ONAME2Style.put(OTYPE, mapONAME2Style); } // 获取或创建ONAME Object[] themeStyle = mapONAME2Style.get(ONAME); if(themeStyle == null) { themeStyle = new Object[SMTMapThemeDef._styleCount]; mapONAME2Style.put(ONAME, themeStyle); } // 合并style for(SMTMapThemeStyleID styleId : SMTMapThemeStyleID.values()) { String styleName = styleId.toString(); if("MAX".equals(styleName)) continue; int pos = rec.getColIndex(styleName); if(pos < 0) continue; Object value; if(styleName.endsWith("COLOR") || styleName.equals("TSTRING")) value = rec.getString(pos); else value = rec.getInteger(pos); if(value == null) continue; themeStyle[styleId.ordinal()] = value; } } public void styleToJson(SMTJsonWriter jsonWr) { Map mapKey2Styles = new LinkedHashMap<>(); // 加入元素 for(Entry> entryOTYPE : _mapOTYPE2ONAME2Style.entrySet()) { StringBuilder sbStyleKey = new StringBuilder(); jsonWr.beginMap("O_" + entryOTYPE.getKey()); for(Entry entryONAME : entryOTYPE.getValue().entrySet()) { // 计算当前元素的style的key Object[] styles = entryONAME.getValue(); sbStyleKey.setLength(0); for(SMTMapThemeStyleID styleId : SMTMapThemeStyleID.values()) { if(styleId.toString().equals("TSTRING")) continue; Object value = styles[styleId.ordinal()]; sbStyleKey.append((value == null ? "null" : SMTStatic.toString(value)) + ","); } // 根据key找到对应的style,如果不存在,则创建 SMTMapThemeStyleCache styleCache = mapKey2Styles.get(sbStyleKey.toString()); if(styleCache == null) { styleCache = new SMTMapThemeStyleCache(styles, mapKey2Styles.size()); mapKey2Styles.put(sbStyleKey.toString(), styleCache); } // 将对象加入元素表 String ONAME = entryONAME.getKey(); jsonWr.beginMap(ONAME); { jsonWr.addKeyValue("style_id", styleCache._pos); String TSTRING = (String)styles[SMTMapThemeStyleID.TSTRING.ordinal()]; if(!SMTStatic.isNullOrEmpty(TSTRING)) jsonWr.addKeyValue("TSTRING", TSTRING); } jsonWr.endMap(); } jsonWr.endMap(); } // 加入风格 jsonWr.beginArray("styles"); for(Entry entry : mapKey2Styles.entrySet()) { jsonWr.beginMap(null); for(SMTMapThemeStyleID styleId : SMTMapThemeStyleID.values()) { if(styleId.toString().equals("TSTRING")) continue; Object value = entry.getValue()._styles[styleId.ordinal()]; if(value == null) continue; jsonWr.addKeyValue(styleId.toString(), SMTStatic.toString(value)); } jsonWr.endMap(); } jsonWr.endArray(); } } protected String _id; protected String _title; protected String _group; protected static int _styleCount = SMTMapThemeStyleID.values().length; protected List _listThemeStyleDef = new ArrayList<>(); public void initInstance(DBRecord rec) throws Exception { _id = rec.getString("theme_id"); _title = rec.getString("theme_title"); _group = rec.getString("theme_group"); Json jsonThemeList = Json.read(rec.getString("theme_legend")); for(Json jsonTheme : jsonThemeList.getJson("themes").asJsonList()) { SMTMapThemeStyleDef themeStyleDef = new SMTMapThemeStyleDef(jsonTheme); _listThemeStyleDef.add(themeStyleDef); } } public void legendToJson(SMTJsonWriter jsonWr) { jsonWr.beginArray("legends"); for(SMTMapThemeStyleDef themeStyleDef : _listThemeStyleDef) { for(Entry entry : themeStyleDef._mapStyle2Legend.entrySet()) { SMTMapThemeLegendStyle legendStyle = entry.getValue(); if(SMTStatic.isNullOrEmpty(legendStyle._title)) continue; jsonWr.beginMap(null); { jsonWr.addKeyValue("title", legendStyle._title); jsonWr.addKeyValue("style", entry.getKey()); jsonWr.addKeyValue("default", legendStyle._default.replace("'", "")); jsonWr.addKeyValue("operate", legendStyle._columnDef._op); jsonWr.beginArray("legend"); for(SMTMapThemeLegendValue legendValue : legendStyle._listLegendValue) { jsonWr.beginMap(null); { jsonWr.addKeyValue("style", legendValue._style.replace("'", "")); jsonWr.addKeyValue("value", legendValue._value.replace("'", "").replace("::timestamp", "")); } jsonWr.endMap(); } jsonWr.endArray(); } jsonWr.endMap(); } } jsonWr.endArray(); } private static String convStyleLegendStyle(String styleName, String style) { if(styleName.endsWith("COLOR")) return "'" + style + "'"; return style; } public String getId() { return _id; } public String getTitle() { return _title; } public String getGroup() { return _group; } public void queryThemeStyles(ASTDBMap dbMap, Date curTime, SMTMapThemeStyleMap themeStyleMap) throws Exception { for(SMTMapThemeStyleDef themeStyleDef : _listThemeStyleDef) { themeStyleDef.queryThemeStyles(dbMap, curTime, themeStyleMap); } } }