package com.smtaiserver.smtaiserver.gismap;
|
|
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 org.dom4j.Document;
|
import org.dom4j.Element;
|
import org.dom4j.Node;
|
import org.springframework.web.servlet.ModelAndView;
|
|
import com.smtaiserver.smtaiserver.core.SMTAIServerApp;
|
import com.smtaiserver.smtaiserver.core.SMTAIServerRequest;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase.DBQueryNotify;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecord;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecords;
|
import com.smtservlet.util.Json;
|
import com.smtservlet.util.SMTJsonWriter;
|
import com.smtservlet.util.SMTStatic;
|
|
public class SMTGisMapLayerDef
|
{
|
protected static String _sqlTemplateHead =
|
"WITH grid AS (\r\n"
|
+ " -- 将点映射到 100x100 的网格\r\n"
|
+ " SELECT\r\n"
|
+ " ST_SnapToGrid(shape, {grid}, {grid}) AS grid_geom,\r\n"
|
+ " shape,{column_names}\r\n"
|
+ " FROM(\r\n"
|
;
|
|
protected static String _sqlTemplateTail =
|
" ) T1 WHERE\r\n"
|
+ " shape && ST_TileEnvelope({zxy})\r\n"
|
+ "),\r\n"
|
+ "unique_points AS (\r\n"
|
+ " -- 从每个网格中选择一个点\r\n"
|
+ " SELECT\r\n"
|
+ " DISTINCT ON (grid_geom) shape, {column_names}\r\n"
|
+ " FROM\r\n"
|
+ " grid\r\n"
|
+ "),\r\n"
|
+ "mvtgeom AS(\r\n"
|
+ "SELECT\r\n"
|
+ " ST_AsMVTGeom(shape, ST_TileEnvelope({zxy}),\r\n"
|
+ " extent => {extent}) AS geom,\r\n"
|
+ " {column_names}\r\n"
|
+ "FROM\r\n"
|
+ " unique_points\r\n"
|
+ " where \r\n"
|
+ " shape && ST_TileEnvelope({zxy})\r\n"
|
+ ")\r\n"
|
+ "SELECT ST_AsMVT(mvtgeom.*)\r\n"
|
+ "FROM mvtgeom";
|
|
|
protected Double _maxRatio;
|
protected Double _minRatio;
|
protected String _icon;
|
protected String _layerId;
|
protected String _title;
|
protected String _dsId;
|
protected String _groupName;
|
protected String _columnNames;
|
protected List<SMTMapLayerSqlXml> _listSqlxmlDrawSql = new ArrayList<>();
|
protected List<SMTMapLayerSqlXml> _listSqlxmlSearchSql = new ArrayList<>();
|
protected int _gridBase = 0;
|
protected Integer[] _grids = new Integer[] {
|
100
|
,62
|
,38
|
,15
|
,5
|
,1
|
};
|
|
public SMTGisMapLayerDef(SMTDatabase db, DBRecord rec) throws Exception
|
{
|
_layerId = rec.getString("layer_id");
|
_title = rec.getString("layer_title");
|
_groupName = rec.getString("layer_group");
|
_minRatio = rec.getDouble("min_ratio");
|
_maxRatio = rec.getDouble("max_ratio");
|
String iconStr = rec.getString("layer_icon");
|
if(!SMTStatic.isNullOrEmpty(iconStr))
|
_icon = Json.read("{\"icon\":\"" + rec.getString("layer_icon") + "\"}").getJson("icon").asString();
|
Document doc = SMTStatic.convStrToXmlDoc("<ROOT>" + rec.getString("layer_sql_xml") + "</ROOT>");
|
Element xmlDrawSqlList = (Element) doc.selectSingleNode("ROOT/DRAW_SQL_LIST");
|
if(xmlDrawSqlList == null)
|
throw new Exception("can't find DRAW_SQL_LIST");
|
|
Element xmlDrawZGrid = (Element)doc.selectSingleNode("ROOT/DRAW_Z_TO_GRID");
|
if(xmlDrawZGrid != null)
|
{
|
_gridBase = SMTStatic.toInt(SMTStatic.getXmlAttr(xmlDrawZGrid, "base", "0"));
|
String[] values = xmlDrawZGrid.getText()
|
.replace("\r", "")
|
.replace("\n", "")
|
.replace(" ", "")
|
.replace("\t", "")
|
.split(",")
|
;
|
|
List<Integer> listGrid = new ArrayList<>();
|
for(int i = 0; i < values.length; i ++)
|
{
|
if(SMTStatic.isNullOrEmpty(values[i]))
|
continue;
|
listGrid.add(Integer.parseInt(values[i]));
|
}
|
_grids = listGrid.toArray(new Integer[listGrid.size()]);
|
}
|
|
_dsId = SMTStatic.getXmlAttr(xmlDrawSqlList, "ds_id");
|
_columnNames = SMTStatic.getXmlAttr(xmlDrawSqlList, "columns");
|
|
for(Node nodeDrawSql : xmlDrawSqlList.selectNodes("DRAW_SQL"))
|
{
|
SMTMapLayerSqlXml sqlxmlDrawSql = new SMTMapLayerSqlXml((Element)nodeDrawSql);
|
_listSqlxmlDrawSql.add(sqlxmlDrawSql);
|
}
|
|
StringBuilder sbSQL = new StringBuilder();
|
List<Object> sqlParams = new ArrayList<>();
|
|
sbSQL.append("SELECT min(st_xmin(shape)) l, min(st_ymin(shape)) t, max(st_xmax(shape)) r, max(st_ymax(shape)) b FROM (\n");
|
|
Map<String, Object> mapSqlXmlArgs = new HashMap<>();
|
mapSqlXmlArgs.put("cur_time", new Date());
|
|
for(int i = 0; i < _listSqlxmlDrawSql.size(); i ++)
|
{
|
if(i > 0)
|
sbSQL.append("\r\nUNION ALL\r\n");
|
|
_listSqlxmlDrawSql.get(i).createSQL(mapSqlXmlArgs, sbSQL, sqlParams);
|
}
|
sbSQL.append(")T");
|
|
Element xmlSearchSQLList = (Element)doc.selectSingleNode("ROOT/SEARCH_SQL_LIST");
|
if(xmlSearchSQLList != null)
|
{
|
for(Node nodeSearchSQL : xmlSearchSQLList.selectNodes("SEARCH_SQL"))
|
{
|
SMTMapLayerSqlXml sqlxmlDrawSql = new SMTMapLayerSqlXml((Element)nodeSearchSQL);
|
_listSqlxmlSearchSql.add(sqlxmlDrawSql);
|
}
|
}
|
}
|
|
public Double getMinRatio()
|
{
|
return _minRatio;
|
}
|
|
public Double getMaxRatio()
|
{
|
return _maxRatio;
|
}
|
|
public String getIcon()
|
{
|
return _icon;
|
}
|
|
public String getGroupName()
|
{
|
return _groupName;
|
}
|
|
public String getLayerId()
|
{
|
return _layerId;
|
}
|
|
public String getTitle()
|
{
|
return _title;
|
}
|
|
public ModelAndView queryVectorTileToResponse(SMTAIServerRequest tranReq, int z, int x, int y) throws Exception
|
{
|
SMTDatabase db = SMTAIServerApp.getApp().allocDatabase();
|
try
|
{
|
int gridZ = Math.max(z - _gridBase, 0);
|
int grid = gridZ < _grids.length ? _grids[gridZ] : 1;
|
StringBuilder sbSQL = new StringBuilder();
|
List<Object> sqlParams = new ArrayList<>();
|
sbSQL.append(_sqlTemplateHead);
|
|
Map<String, Object> mapSqlXmlArgs = new HashMap<>();
|
mapSqlXmlArgs.put("cur_time", new Date());
|
|
for(int i = 0; i < _listSqlxmlDrawSql.size(); i ++)
|
{
|
if(i > 0)
|
sbSQL.append("\r\nUNION ALL\r\n");
|
|
_listSqlxmlDrawSql.get(i).createSQL(mapSqlXmlArgs, sbSQL, sqlParams);
|
}
|
sbSQL.append(_sqlTemplateTail);
|
|
String sql = sbSQL.toString()
|
.replace("{zxy}", String.format("%d, %d, %d", z, x, y))
|
.replace("{extent}", "4096")
|
.replace("{grid}", "" + grid)
|
.replace("{column_names}", _columnNames);
|
;
|
|
|
DBRecords recs = db.querySQL(sql, sqlParams.toArray(new Object[sqlParams.size()]));
|
|
byte[] data = (byte[])recs.getRecord(0).getValue(0);
|
|
return tranReq.returnDownloadByteArray(data, "a", "application/octet-stream");
|
}
|
finally
|
{
|
db.close();
|
}
|
}
|
|
//SMTMapLayerSqlXml> _listSqlxmlSearchSql
|
|
public void searchElement(SMTDatabase db, Date time, String searchText, int[] count, SMTJsonWriter jsonWr) throws Exception
|
{
|
Map<String, Object> mapArgs = new HashMap<>();
|
mapArgs.put("cur_time", time);
|
mapArgs.put("search_str", searchText);
|
for(SMTMapLayerSqlXml xmlSearchSQL : _listSqlxmlSearchSql)
|
{
|
StringBuilder sbSQL = new StringBuilder();
|
List<Object> sqlParams = new ArrayList<>();
|
xmlSearchSQL.createSQL(mapArgs, sbSQL, sqlParams);
|
|
db.querySQLNotify(sbSQL.toString(), sqlParams.toArray(new Object[sqlParams.size()]), new DBQueryNotify()
|
{
|
@Override
|
public boolean onNextRecord(DBRecord rec) throws Exception
|
{
|
jsonWr.beginMap(null);
|
for(Entry<String, Integer> entry : rec.getFieldMap().entrySet())
|
{
|
jsonWr.addKeyValue(entry.getKey(), rec.getString(entry.getValue()));
|
}
|
jsonWr.endMap();
|
|
count[0] ++;
|
if(count[0] >= count[1])
|
return false;
|
return true;
|
}
|
|
});
|
}
|
}
|
}
|