From adf63267324cd6077ff57d2647903b0dd1d96f3c Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Fri, 15 Jul 2022 00:24:15 -0400 Subject: [PATCH] =?UTF-8?q?perf(=E4=BB=AA=E8=A1=A8=E6=9D=BF):=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96echarts=E5=9C=B0=E5=9B=BE=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=B8=96=E7=95=8C=E5=9C=B0=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/dataease/map/api/MapApi.java | 14 +- .../io/dataease/map/dto/entity/Constants.java | 3 + .../io/dataease/map/server/MapServer.java | 31 +-- .../io/dataease/map/service/MapService.java | 19 +- .../java/io/dataease/map/utils/MapUtils.java | 259 +++++++----------- frontend/src/api/map/map.js | 8 + 6 files changed, 126 insertions(+), 208 deletions(-) diff --git a/backend/src/main/java/io/dataease/map/api/MapApi.java b/backend/src/main/java/io/dataease/map/api/MapApi.java index 88e179ddbf..58a839443f 100644 --- a/backend/src/main/java/io/dataease/map/api/MapApi.java +++ b/backend/src/main/java/io/dataease/map/api/MapApi.java @@ -10,21 +10,13 @@ import java.util.List; @RequestMapping("/api/map") public interface MapApi { - @GetMapping("/resourceFull/{areaCode}") - String resourceFull(@PathVariable String areaCode); - @GetMapping("/asyncGeometry") - String asyncGeometry(); @GetMapping("/areaEntitys/{pcode}") List areaEntitys(@PathVariable String pcode); - /** - * 由于api有限流机制 - * 请求失败后 调用重试方法 - * @param areaCode - */ - @GetMapping("/retry/{areaCode}") - void retry(@PathVariable String areaCode); + @GetMapping("/globalEntitys/{pcode}") + List globalEntitys(@PathVariable String pcode); + } diff --git a/backend/src/main/java/io/dataease/map/dto/entity/Constants.java b/backend/src/main/java/io/dataease/map/dto/entity/Constants.java index 5cd4bbcee8..e70c6e2b10 100644 --- a/backend/src/main/java/io/dataease/map/dto/entity/Constants.java +++ b/backend/src/main/java/io/dataease/map/dto/entity/Constants.java @@ -2,6 +2,9 @@ package io.dataease.map.dto.entity; public class Constants { + public static final String COUNTRY_CODE = "国gb"; + public static final String COUNTRY_NAME = "国name"; + public static final String PROVINCE_CODE = "省gb"; public static final String PROVINCE_NAME = "省name"; diff --git a/backend/src/main/java/io/dataease/map/server/MapServer.java b/backend/src/main/java/io/dataease/map/server/MapServer.java index d3cdc5af3e..82e54caca8 100644 --- a/backend/src/main/java/io/dataease/map/server/MapServer.java +++ b/backend/src/main/java/io/dataease/map/server/MapServer.java @@ -15,28 +15,9 @@ import java.util.List; @RestController public class MapServer implements MapApi { - - @Resource private MapService mapService; - @Override - public String resourceFull(@PathVariable String areaCode) { - return mapService.geometry(areaCode); - } - - @Override - public String asyncGeometry() { - try { - List areaEntities = mapService.areaEntities(); - MapUtils.recursionWriteFull(areaEntities); - }catch (Exception e) { - LogUtil.error(e); - return e.getMessage(); - } - return "async success"; - } - @Override public List areaEntitys(@PathVariable String pcode) { List areaEntities = mapService.areaEntities(); @@ -47,11 +28,11 @@ public class MapServer implements MapApi { } @Override - public void retry(@PathVariable String areaCode) { - List areaEntities = mapService.areaEntities(); - AreaEntity areaEntity = MapUtils.nodeByCode(areaEntities, areaCode); - List targets = new ArrayList<>(); - targets.add(areaEntity); - MapUtils.recursionWriteFull(targets); + public List globalEntitys(String pcode) { + List areaEntities = mapService.globalEntities(); + if (StringUtils.equals(pcode, "0")) { + return areaEntities; + } + return mapService.entitysByPid(areaEntities, pcode); } } diff --git a/backend/src/main/java/io/dataease/map/service/MapService.java b/backend/src/main/java/io/dataease/map/service/MapService.java index d159cac3cb..ac21dc9052 100644 --- a/backend/src/main/java/io/dataease/map/service/MapService.java +++ b/backend/src/main/java/io/dataease/map/service/MapService.java @@ -1,6 +1,5 @@ package io.dataease.map.service; - import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.io.file.FileReader; import io.dataease.map.dto.entity.AreaEntity; @@ -14,22 +13,20 @@ import java.util.List; @Service public class MapService { - private static final String dirPath = "/opt/dataease/data/feature/"; - // 要不要加缓存呢? - public String geometry(String areaCode) { - String path = dirPath + "full/" + areaCode + "_full.json"; - FileReader fileReader = new FileReader(path); - return fileReader.readString(); - } - @Cacheable("sys_map_areas") public List areaEntities() { List areaEntities = MapUtils.readAreaEntity(); return areaEntities; } + @Cacheable("sys_map_areas") + public List globalEntities() { + List areaEntities = MapUtils.readGlobalAreaEntity(); + return areaEntities; + } + public List entitysByPid(List entities, String pid) { for (int i = 0; i < entities.size(); i++) { AreaEntity areaEntity = entities.get(i); @@ -39,7 +36,7 @@ public class MapService { if (CollectionUtil.isNotEmpty(areaEntity.getChildren())) { List areaEntities = entitysByPid(areaEntity.getChildren(), pid); - if (null != areaEntities){ + if (null != areaEntities) { return areaEntities; } } @@ -48,6 +45,4 @@ public class MapService { } - - } diff --git a/backend/src/main/java/io/dataease/map/utils/MapUtils.java b/backend/src/main/java/io/dataease/map/utils/MapUtils.java index a016cecd48..7a35805a96 100644 --- a/backend/src/main/java/io/dataease/map/utils/MapUtils.java +++ b/backend/src/main/java/io/dataease/map/utils/MapUtils.java @@ -1,17 +1,16 @@ package io.dataease.map.utils; -import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.io.file.FileWriter; import cn.hutool.core.util.StrUtil; -import cn.hutool.json.JSONUtil; +import io.dataease.map.dto.entity.AreaEntity; +import io.dataease.map.dto.entity.Constants; import io.dataease.plugins.common.base.domain.AreaMapping; import io.dataease.plugins.common.base.domain.AreaMappingExample; +import io.dataease.plugins.common.base.domain.AreaMappingGlobal; +import io.dataease.plugins.common.base.domain.AreaMappingGlobalExample; +import io.dataease.plugins.common.base.mapper.AreaMappingGlobalMapper; import io.dataease.plugins.common.base.mapper.AreaMappingMapper; -import io.dataease.commons.utils.LogUtil; -import io.dataease.map.dto.entity.*; -import io.dataease.map.dto.entity.Properties; -import io.dataease.map.dto.response.MapResponse; -import io.dataease.map.dto.response.MapResultDto; + +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.*; @@ -21,24 +20,33 @@ import java.util.stream.Collectors; @Component public class MapUtils { - private static AreaMappingMapper areaMappingMapper; + private static AreaMappingGlobalMapper areaMappingGlobalMapper; + @Autowired public void setAreaMappingMapper(AreaMappingMapper areaMappingMapper) { MapUtils.areaMappingMapper = areaMappingMapper; } - private static final String path = "/opt/dataease/data/行政区划列表2020-03.xlsx"; - private static final String featureDir = "/opt/dataease/data/feature/"; + @Autowired + public void setAreaMappingGlobalMapper(AreaMappingGlobalMapper areaMappingGlobalMapper) { + MapUtils.areaMappingGlobalMapper = areaMappingGlobalMapper; + } + private static final String featureDir = "/opt/dataease/data/feature/"; public static String formatCode(String code) { return code; } + public static List readGlobalCodes() { + AreaMappingGlobalExample example = new AreaMappingGlobalExample(); + List mappingGlobals = areaMappingGlobalMapper.selectByExample(example); + return mappingGlobals; + } - public static List> readCodeList( ) { + public static List> readCodeList() { AreaMappingExample example = new AreaMappingExample(); List areaMappings = areaMappingMapper.selectByExample(example); return areaMappings.stream().map(mapping -> { @@ -54,6 +62,74 @@ public class MapUtils { }).collect(Collectors.toList()); } + public static List readGlobalAreaEntity() { + List maps = readGlobalCodes(); + Map countryMap = new ConcurrentHashMap<>(); + Map provinceMap = new ConcurrentHashMap<>(); + Map cityMap = new ConcurrentHashMap<>(); + Map countyMap = new ConcurrentHashMap<>(); + AreaEntity globalRoot = globalRoot(); + maps.stream().forEach(map -> { + String country_code = map.getCountryCode(); + String province_code = map.getProvinceCode(); + String city_code = map.getCityCode(); + String county_code = map.getCountyCode(); + // 是否是跨级直辖 + Boolean isCrossLevel = StrUtil.equals(province_code, city_code) + && !StrUtil.equals(province_code, "156710000"); + + if (!countryMap.containsKey(country_code)) { + String country_name = map.getCountryName(); + AreaEntity child = AreaEntity.builder().code(country_code).name(country_name) + .pcode(globalRoot.getCode()).build(); + + countryMap.put(country_code, child); + globalRoot.addChild(child); + } + + AreaEntity currentCountry = countryMap.get(country_code); + + String province_name = map.getProvinceName(); + if (!provinceMap.containsKey(province_code)) { + AreaEntity child = AreaEntity.builder().code(province_code).name(province_name) + .pcode(currentCountry.getCode()).build(); + provinceMap.put(province_code, child); + currentCountry.addChild(child); + } + + // 当前省 + AreaEntity currentProvince = provinceMap.get(province_code); + + String city_name = map.getCityName(); + if (isCrossLevel) { + city_code = county_code; + city_name = map.getCountyName(); + } + if (StringUtils.isNotBlank(city_code) && !cityMap.containsKey(city_code)) { + AreaEntity child = AreaEntity.builder().code(city_code).name(city_name).pcode(currentProvince.getCode()) + .build(); + cityMap.put(city_code, child); + currentProvince.addChild(child); + } + if (StringUtils.isNotBlank(county_code) && !isCrossLevel) { + // 当前市 + AreaEntity currentCity = cityMap.get(city_code); + if (!countyMap.containsKey(county_code)) { + String county_name = map.getCountyName(); + AreaEntity child = AreaEntity.builder().code(county_code).name(county_name) + .pcode(currentCity.getCode()) + .build(); + countyMap.put(county_code, child); + currentCity.addChild(child); + } + } + }); + + List result = new ArrayList<>(); + result.add(globalRoot); + return result; + } + public static List readAreaEntity() { List> maps = readCodeList(); @@ -75,15 +151,15 @@ public class MapUtils { // 是否是跨级直辖 Boolean isCrossLevel = StrUtil.equals(province_code, city_code) && !StrUtil.equals(province_code, "710000"); - if (!provinceMap.containsKey(province_code)) { String province_name = map.get(Constants.PROVINCE_NAME).toString(); - AreaEntity child = AreaEntity.builder().code(province_code).name(province_name).pcode(china.getCode()).build(); + AreaEntity child = AreaEntity.builder().code(province_code).name(province_name).pcode(china.getCode()) + .build(); provinceMap.put(province_code, child); china.addChild(child); } - //当前省 + // 当前省 AreaEntity currentProvince = provinceMap.get(province_code); String city_name = map.get(Constants.CITY_NAME).toString(); @@ -92,16 +168,19 @@ public class MapUtils { city_name = map.get(Constants.COUNTY_NAME).toString(); } if (!cityMap.containsKey(city_code)) { - AreaEntity child = AreaEntity.builder().code(city_code).name(city_name).pcode(currentProvince.getCode()).build(); + AreaEntity child = AreaEntity.builder().code(city_code).name(city_name).pcode(currentProvince.getCode()) + .build(); cityMap.put(city_code, child); currentProvince.addChild(child); } if (!isCrossLevel) { - //当前市 + // 当前市 AreaEntity currentCity = cityMap.get(city_code); if (!countyMap.containsKey(county_code)) { String county_name = map.get(Constants.COUNTY_NAME).toString(); - AreaEntity child = AreaEntity.builder().code(county_code).name(county_name).pcode(currentCity.getCode()).build(); + AreaEntity child = AreaEntity.builder().code(county_code).name(county_name) + .pcode(currentCity.getCode()) + .build(); countyMap.put(county_code, child); currentCity.addChild(child); } @@ -116,148 +195,8 @@ public class MapUtils { return AreaEntity.builder().code("100000").name("中华人民共和国").build(); } - public static void recursionWrite(List areaEntityList) { - areaEntityList.forEach(areaEntity -> { - String code = areaEntity.getCode(); - MapResponse mapResponse = HttpUtils.get(code); - if (StrUtil.equals("1", mapResponse.getStatus()) && StrUtil.equalsAnyIgnoreCase("ok", mapResponse.getInfo()) && StrUtil.equalsAnyIgnoreCase("10000", mapResponse.getInfocode())) { - List districts = mapResponse.getDistricts(); - if (CollectionUtil.isNotEmpty(districts)) { - List kidFeatures = districts.stream().map(district -> buildFeature(district, areaEntity)).collect(Collectors.toList()); - MapResultDto mapResultDto = buildGeometry(kidFeatures); - writeFeatureFile(mapResultDto, areaEntity.getCode()); - } - - } - - if (CollectionUtil.isNotEmpty(areaEntity.getChildren())) { - recursionWrite(areaEntity.getChildren()); - } - }); - + private static AreaEntity globalRoot() { + return AreaEntity.builder().code("000000000").name("地球村").build(); } - public static void recursionWriteFull(List areaEntityList) { - areaEntityList.forEach(areaEntity -> { - - List childrens = areaEntity.getChildren(); - if (CollectionUtil.isEmpty(childrens)) { - childrens = new ArrayList<>(); - childrens.add(areaEntity); - } - - List features = new ArrayList<>(); - - childrens.stream().forEach(child -> { - MapResponse mapResponse = HttpUtils.get(child.getCode()); - if (StrUtil.equals("1", mapResponse.getStatus()) && StrUtil.equalsAnyIgnoreCase("ok", mapResponse.getInfo()) && StrUtil.equalsAnyIgnoreCase("10000", mapResponse.getInfocode())) { - List districts = mapResponse.getDistricts(); - if (CollectionUtil.isNotEmpty(districts)) { - List kidFeatures = districts.stream().map(district -> buildFeature(district, child)).collect(Collectors.toList()); - features.addAll(kidFeatures); - } - }else { - LogUtil.error("请求节点错误 请手动补偿: " + areaEntity.getName() +" -> "+child.getName()); - } - }); - - if (CollectionUtil.isNotEmpty(features)) { - MapResultDto mapResultDto = buildGeometry(features); - writeFeatureFileFull(mapResultDto, areaEntity.getCode() + "_full"); - } - - if (CollectionUtil.isNotEmpty(areaEntity.getChildren())) { - recursionWriteFull(areaEntity.getChildren()); - } - - - }); - - } - - public static Feature buildFeature(District district, AreaEntity areaEntity) { - String type = "Feature"; - Properties properties = new Properties(); - properties.setAdcode(district.getAdcode()); - properties.setName(district.getName()); - properties.setCenter(Arrays.stream(district.getCenter().split(",")).map(Double::parseDouble).collect(Collectors.toList())); - properties.setCentroid(properties.getCenter()); - properties.setChildrenNum(CollectionUtil.isNotEmpty(areaEntity.getChildren()) ? areaEntity.getChildren().size() : 0); - properties.setLevel(district.getLevel()); - Parent parent = new Parent(); - parent.setAdcode(areaEntity.getPcode()); - properties.setParent(parent); - - String polylineStr = district.getPolyline(); - String[] polylines = polylineStr.split("[|]"); - List>>> multiPolygon = Arrays.stream(polylines).map(polyline -> { - String[] strings = polyline.split(";"); - List> line = Arrays.stream(strings).map(str -> { - String[] pointstr = str.split(","); - List strPoint = Arrays.asList(pointstr); - List point = strPoint.stream().map(Double::parseDouble).collect(Collectors.toList()); - return point; - }).collect(Collectors.toList()); - List firstPoint = line.get(0); - List lastPoint = line.get(line.size() - 1); - // 线的起始点和终点没有重合 说明没有闭合 需要手动闭合 - if (firstPoint.get(0) != lastPoint.get(0) || firstPoint.get(1) != lastPoint.get(1)) { - line.add(firstPoint); - } - List>> polygon = new ArrayList<>(); - polygon.add(line); - return polygon; - }).collect(Collectors.toList()); - - Geometry geometry = new Geometry(); - geometry.setType("MultiPolygon"); - geometry.setCoordinates(multiPolygon); - - Feature feature = new Feature(); - feature.setType(type); - feature.setProperties(properties); - feature.setGeometry(geometry); - return feature; - } - - - - - - public static MapResultDto buildGeometry(List features) { - MapResultDto mapResultDto = new MapResultDto(); - mapResultDto.setType("FeatureCollection"); - mapResultDto.setFeatures(features); - return mapResultDto; - } - - public static void writeFeatureFile(MapResultDto mapResultDto, String fileName) { - String path = featureDir + fileName + ".json"; - FileWriter fileWriter = new FileWriter(path); - String content = JSONUtil.toJsonStr(mapResultDto); - fileWriter.write(content); - } - - public static void writeFeatureFileFull(MapResultDto mapResultDto, String fileName) { - String path = featureDir + "full/" + fileName + ".json"; - FileWriter fileWriter = new FileWriter(path); - String content = JSONUtil.toJsonStr(mapResultDto); - fileWriter.write(content); - } - - public static AreaEntity nodeByCode(List areaEntities, String code) { - for (int i = 0; i < areaEntities.size(); i++) { - AreaEntity areaEntity = areaEntities.get(i); - if (StrUtil.equals(areaEntity.getCode(), code)) { - return areaEntity; - } - if (CollectionUtil.isNotEmpty(areaEntity.getChildren())) { - AreaEntity temp = nodeByCode(areaEntity.getChildren(), code); - if (null != temp){ - return temp; - } - } - } - return null; - } } diff --git a/frontend/src/api/map/map.js b/frontend/src/api/map/map.js index 19257ef9cf..be82bdc9a6 100644 --- a/frontend/src/api/map/map.js +++ b/frontend/src/api/map/map.js @@ -8,6 +8,14 @@ export const areaMapping = () => { }) } +export const globalMapping = () => { + return request({ + url: '/api/map/globalEntitys/0', + method: 'get', + loading: true + }) +} + export function geoJson(areaCode) { return request({ url: '/geo/' + areaCode + '_full.json',