构建电子地图网站——04 启动加载本地缓存:web+InitializingBean
2022-11-23 14:20:08

前2节已经搭建好了开发平台,并通过03节的改变,已经能够对空间数据进行增删改查了,那么接下来继续对项目进行改造,以兼容更多的geometry类型,,并只需要对对3张表进行一个查询操作。由于数据库中的数据较多,直接查库较慢,所以我们把内容存在本地内存中,从内存中访问,本节主要是启动加载本地缓存

1 model

把原先的PointModel类改成GeometryModel类,以兼容更多的geometry类型,相关的属性则是根据数据库中表的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Getter
@Setter
@ToString
public class GeometryModel {
private Integer gId;
private String namePy;
private String nameCh;
private String nameFt;
private String presLoc;
private String typePy;
private String typeCh;
private String levRank;
private Integer begYr;
private String begRule;
private Integer endYr;
private String endRule;
private String geoSrc;
private String compiler;
private String gecomplr;
private String checker;
private String entDate;
private String begChgTy;
private String endChgTy;
private Geometry geometry;
}

2 dao

只需要查询,并查询三张表。把不必要的删掉,补充需要的

1
2
3
4
5
6
7
8
9
@Service
public interface MapDao {
//针对v6_time_cnty_pts_utf_wgs84表
GeometryModel getCntyPoint(@Param("gId") Integer gId);
//针对v6_time_pref_pts_utf_wgs84表
GeometryModel getPrefPoint(@Param("gId") Integer gId);
//针对v6_time_pref_pgn_utf_wgs84表
GeometryModel getprefPolygon(@Param("gId") Integer gId);
}

3 mapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//http://mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.cc.dao.MapDao" >
<resultMap id="geometryModelResult" type="com.cc.model.GeometryModel">
<result property="gId" column="gid" jdbcType="BIGINT"/>
<result property="namePy" column="name_py" jdbcType="VARCHAR"/>
<result property="nameCh" column="name_ch" jdbcType="VARCHAR"/>
<result property="nameFt" column="name_ft" jdbcType="VARCHAR"/>
<result property="presLoc" column="pres_loc" jdbcType="VARCHAR"/>
<result property="typePy" column="type_py" jdbcType="VARCHAR"/>
<result property="typeCh" column="type_ch" jdbcType="VARCHAR"/>
<result property="levRank" column="lev_rank" jdbcType="VARCHAR"/>
<result property="begYr" column="beg_yr" jdbcType="BIGINT"/>
<result property="begRule" column="beg_rule" jdbcType="VARCHAR"/>
<result property="endYr" column="end_yr" jdbcType="BIGINT"/>
<result property="endRule" column="end_rule" jdbcType="VARCHAR"/>
<result property="geoSrc" column="geo_src" jdbcType="VARCHAR"/>
<result property="compiler" column="compiler" jdbcType="VARCHAR"/>
<result property="gecomplr" column="gecomplr" jdbcType="VARCHAR"/>
<result property="checker" column="checker" jdbcType="VARCHAR"/>
<result property="entDate" column="ent_date" jdbcType="VARCHAR"/>
<result property="begChgTy" column="beg_chg_ty" jdbcType="VARCHAR"/>
<result property="endChgTy" column="end_chg_ty" jdbcType="VARCHAR"/>
<result property="geometry" column="geom" typeHandler="com.cc.mybatis.GeometryTypeHandler"/>
</resultMap>

<sql id="CNTY_PTS">
v6_time_cnty_pts_utf_wgs84
</sql>
<sql id="PREF_PTS">
v6_time_pref_pts_utf_wgs84
</sql>
<sql id="PREF_PGN">
v6_time_pref_pgn_utf_wgs84
</sql>
<sql id="BASE_COLUMN">
gid,name_py,name_ch,name_ft,pres_loc,type_py,type_ch,lev_rank,beg_yr,beg_rule,end_yr,end_rule,geo_src,compiler,gecomplr,checker,ent_date,beg_chg_ty,end_chg_ty,geom
</sql>

<select id="getCntyPoint" resultMap="geometryModelResult">
SELECT
<include refid="BASE_COLUMN"></include>
FROM
<include refid="CNTY_PTS"/>
WHERE gid=#{gId} LIMIT 1
</select>

<select id="getprefPolygon" resultMap="geometryModelResult">
SELECT
<include refid="BASE_COLUMN"></include>
FROM
<include refid="PREF_PGN"/>
WHERE gid=#{gId} LIMIT 1
</select>

<select id="getPrefPoint" resultMap="geometryModelResult">
SELECT
<include refid="BASE_COLUMN"></include>
FROM
<include refid="PREF_PTS"/>
WHERE gid=#{gId} LIMIT 1
</select>
</mapper>

4 localcache

新建一个包localcache==>包下新建一个类GeometryCache.java

直接查库较慢,所以我们把内容存在本地内存中,从内存中访问,这个类继承了InitializingBean,当程序启动的时候,数据就会加载。

程序中加入了map<>,按照表名区分cntypts、prefpts、prefpgn,每张表存成一个list,新建一个查询方法getDynastyGeometry,用表名和时间区间查询对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Service
public class GeometryCache implements InitializingBean {

Map<String, List<GeometryModel>> historyGis =new HashMap<>();

@Autowired
private MapDao mapDao;

@Override
public void afterPropertiesSet() throws Exception {
List<GeometryModel> cntyGeometry=new ArrayList<>();
int i=1;
while (mapDao.getCntyPoint(i)!=null){
cntyGeometry.add(mapDao.getCntyPoint(i));
i++;
}
historyGis.put("cntypts",cntyGeometry);
List<GeometryModel> prefPtsGeometry=new ArrayList<>();
i=1;
while (mapDao.getPrefPoint(i)!=null){
prefPtsGeometry.add(mapDao.getCntyPoint(i));
i++;
}
historyGis.put("prefpts",prefPtsGeometry);
List<GeometryModel> prefPgnGeometry=new ArrayList<>();
i=1;
while (mapDao.getprefPolygon(i)!=null){
prefPgnGeometry.add(mapDao.getprefPolygon(i));
i++;
}
historyGis.put("prefpgn",prefPgnGeometry);
}

public List<GeometryModel> getDynastyGeometry(String category,Integer start,Integer end){
List<GeometryModel> result=new ArrayList<>();
for (GeometryModel g:historyGis.get(category)) {
if((g.getBegYr()>=start && g.getBegYr()<=end)||(g.getEndYr()>=start&&g.getEndYr()<=end)){
result.add(g);
}
}
return result;
}
}

5 Service

接口——MapService

1
2
3
public interface MapService {
List<GeometryModel> getDynastyGeom(String category,Integer start,Integer end);
}

实现类——MapServiceImpl

1
2
3
4
5
6
7
8
9
@Service
public class MapServiceImpl implements MapService {
@Autowired
private GeometryCache geometryCache;
@Override
public List<GeometryModel> getDynastyGeom(String category,Integer start,Integer end){
return geometryCache.getDynastyGeometry(category,start,end);
}
}

6 controller

用json跟前端交互数据,里面有一个方法geometryToJson,将geometry对象转成json,其实geometry.toString也可以将geometry转成String,但String有长度限制,转成json更安全些

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
@Controller
@RequestMapping(value = "/history")
@Slf4j
public class MapController {
@Autowired
private MapService mapService;
/**
* 根据表名和时间区间输出对象
* @param category 表名简写
* @param start 起始时间
* @param end 终止时间
* @return
*/
@ResponseBody
@GetMapping("/geometry")
public JSONObject getPoint(@RequestParam("category") String category,@RequestParam("start") Integer start,@RequestParam("end") Integer end){
try {
List<GeometryModel> result = mapService.getDynastyGeom(category, start, end);
JSONObject jsonObject = new JSONObject();
jsonObject.put("number", result.size());
JSONArray jsonArray = new JSONArray();
for (GeometryModel g : result) {
JSONObject geom = new JSONObject();
geom.put("gid", g.getGId());
geom.put("namepy", g.getNamePy());
geom.put("namech", g.getNameCh());
geom.put("nameft", g.getNameFt());
geom.put("presloc", g.getPresLoc());
geom.put("typepy", g.getTypePy());
geom.put("typech", g.getTypeCh());
geom.put("levrank", g.getLevRank());
geom.put("begyr", g.getBegYr());
geom.put("begrule", g.getBegRule());
geom.put("endyr", g.getEndYr());
geom.put("endrule", g.getEndRule());
geom.put("geosrc", g.getGeoSrc());
geom.put("compiler", g.getCompiler());
geom.put("gecomplr", g.getGecomplr());
geom.put("checker", g.getChecker());
geom.put("entdate", g.getEntDate());
geom.put("begchgty", g.getBegChgTy());
geom.put("endchgty", g.getEndChgTy());
geom.put("geometry", geometryToJson(g.getGeometry()));
jsonArray.add(geom);
}
jsonObject.put("list", jsonArray);
log.info("入参类别:{},起始时间:{},截止时间:{}", category, start, end);
return jsonObject;
}catch (Exception e){
log.error("程序错误类型:",e);
return null;
}
}

private JSONObject geometryToJson(Geometry geometry){
JSONObject jsonObject=new JSONObject();
jsonObject.put("type",geometry.getGeometryType());
JSONArray coorList=new JSONArray();
for (int i=0;i<geometry.getNumGeometries();i++){
JSONArray coors=new JSONArray();
Coordinate[] coordinates=geometry.getGeometryN(i).getCoordinates();
for (Coordinate c:coordinates) {
JSONObject jsonObjectCoor=new JSONObject();
jsonObjectCoor.put("lng",c.x);
jsonObjectCoor.put("lat",c.y);
coors.add(jsonObjectCoor);
}
coorList.add(coors);
}
jsonObject.put("coordinates",coorList);
return jsonObject;
}
}

7 测试

查询v6_time_pref_pgn_utf_wgs84表

http://localhost:8080/history/geometry?category=prefpgn&start=-5000&end=-221

查询v6_time_pref_pts_utf_wgs84表

localhost:8080/history/geometry?category=prefpts&start=-5000&end=-221

查询v6_time_cnty_pts_utf_wgs84表

localhost:8080/history/geometry?category=cntypts&start=-5000&end=-221