优化内存
This commit is contained in:
parent
b206c870fd
commit
f60a0d5474
8
pom.xml
8
pom.xml
@ -13,7 +13,7 @@
|
||||
</properties>
|
||||
<groupId>com.github.deng0515001</groupId>
|
||||
<artifactId>lnglat2Geo</artifactId>
|
||||
<version>1.0.3</version>
|
||||
<version>1.0.4</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>lnglat2Geo</name>
|
||||
<description>lnglat to Geo</description>
|
||||
@ -180,9 +180,9 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<aggregate>true</aggregate>
|
||||
</configuration>
|
||||
<!--<configuration>-->
|
||||
<!--<aggregate>true</aggregate>-->
|
||||
<!--</configuration>-->
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
|
@ -5,6 +5,7 @@ import com.dengxq.lnglat2Geo.entity.CoordinateSystem.CoordinateSystem
|
||||
import com.dengxq.lnglat2Geo.entity.DistrictLevel.DistrictLevel
|
||||
import com.dengxq.lnglat2Geo.entity.{Admin, BusinessArea, BusinessAreaInfo, CoordinateSystem, _}
|
||||
import com.dengxq.lnglat2Geo.utils.GeoUtils
|
||||
import collection.JavaConversions._
|
||||
|
||||
object GeoTrans {
|
||||
|
||||
@ -86,8 +87,8 @@ object GeoTrans {
|
||||
* @param adcode 地区code
|
||||
* @return 规范化的地区信息
|
||||
*/
|
||||
def normalizeName(name: String, level: DistrictLevel): Seq[AdminNode] = {
|
||||
GeoTransImpl.normalizeName(name, level)
|
||||
def normalizeName(name: String, level: DistrictLevel, isFullMatch: Boolean): java.util.List[AdminNode] = {
|
||||
GeoTransImpl.normalizeName(name, level, isFullMatch)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,7 @@ private[lnglat2Geo] object GeoTransImpl {
|
||||
lazy val streetData: Map[Int, AdminNode] = AdminDataProvider.AdminLoader.loadStreetData.map(s => (s.id, s)).toMap
|
||||
lazy val countryCode: Map[String, String] = AdminDataProvider.AdminLoader.loadCountryCode
|
||||
|
||||
lazy val boundaryData: Map[Long, List[(Long, Int, Boolean)]] = AdminDataProvider.AdminLoader.loadBoundaryData
|
||||
lazy val boundaryData: Map[Long, List[(Long, Int, Int)]] = AdminDataProvider.AdminLoader.loadBoundaryData
|
||||
lazy val boundaryIndex: Map[Long, List[Long]] = boundaryData
|
||||
.keySet
|
||||
.map(s => (new S2CellId(s).parent(min_level).id(), s))
|
||||
@ -71,7 +71,7 @@ private[lnglat2Geo] object GeoTransImpl {
|
||||
}
|
||||
|
||||
def getCityLevel(admin: Admin): String = {
|
||||
getCityLevel(admin.cityID.toString)
|
||||
getCityLevel(admin.cityCode.toString)
|
||||
}
|
||||
|
||||
def getCityLevel(adcode_or_name: String): String = {
|
||||
@ -79,19 +79,34 @@ private[lnglat2Geo] object GeoTransImpl {
|
||||
}
|
||||
|
||||
def normalizeName(adcode: Int): AdminNode = {
|
||||
adminData.getOrElse(adcode, null)
|
||||
adminData.getOrElse(adcode, streetData.getOrElse(adcode, null))
|
||||
}
|
||||
|
||||
def normalizeName(name: String, level: DistrictLevel): Seq[AdminNode] = {
|
||||
def normalizeName(name: String, level: DistrictLevel, isFullMatch: Boolean): List[AdminNode] = {
|
||||
adminData.values.filter(_.level.equals(level))
|
||||
.filter(s => s.shortName.contains(name) || s.name.contains(name))
|
||||
.toSeq
|
||||
.filter(s => if (isFullMatch) s.name.equals(name) else s.shortName.contains(name) || s.name.contains(name))
|
||||
.toList
|
||||
}
|
||||
|
||||
def normalizeName(provinceIn: String = "", cityIn: String = "", districtIn: String = "", streetIn: String = "", isFullMatch: Boolean = false): Seq[Admin] = {
|
||||
private val cityNameMap: Map[String, String] = Map(("重庆市", ""), ("上海市", "上海城区"), ("北京市", "北京城区"), ("天津市", "天津城区")
|
||||
,("那曲市", "那曲地区")
|
||||
)
|
||||
|
||||
private val districtNameMap: Map[String, String] = Map(("云州区", "大同县"), ("平城区", "城区"), ("云冈区", "南郊区"),
|
||||
("余江区", "余江县"), ("马龙区", "马龙县"), ("光明区", "宝安区"), ("怀仁区", "怀仁县"), ("彬州市", "彬县"), ("海安市", "海安县"),
|
||||
("漠河市", "漠河县"), ("京山市", "京山县"), ("济阳区", "济阳县"), ("潞州区", "城区"), ("上党区", "长治县"), ("屯留区", "屯留县"), ("潞城区", "潞城市"),
|
||||
("滦州市", "滦县"), ("潜山市", "潜山县"), ("邹平市", "邹平县"), ("荔浦市", "荔浦县"), ("兴仁市", "兴仁县"), ("水富市", "水富县"), ("华亭市", "华亭县"),
|
||||
("积石山县", "积石山保安族东乡族撒拉族自治县"), ("元江县", "元江哈尼族彝族傣族自治县"), ("双江县", "双江拉祜族佤族布朗族傣族自治县"),
|
||||
("孟连县", "孟连傣族拉祜族佤族自治县"), ("镇沅县", "镇沅彝族哈尼族拉祜族自治县"),
|
||||
("大柴旦行政委员会", "海西蒙古族藏族自治州直辖"), ("冷湖行政委员会", "海西蒙古族藏族自治州直辖"), ("茫崖行政委员会", "海西蒙古族藏族自治州直辖"),
|
||||
("上饶县", "广信区"), ("达孜区", "达孜县"),
|
||||
("色尼区", "那曲县")
|
||||
)
|
||||
|
||||
def normalizeName(provinceIn: String = "", cityIn: String = "", districtIn: String = "", streetIn: String = "", isFullMatch: Boolean = false): List[Admin] = {
|
||||
val province = if (provinceIn == null || provinceIn.equals("未知")) "" else provinceIn
|
||||
val city = if (cityIn == null || cityIn.equals("未知")) "" else cityIn
|
||||
val district = if (districtIn == null || districtIn.equals("未知")) "" else districtIn
|
||||
val city = if (cityIn == null || cityIn.equals("未知")) "" else cityNameMap.getOrElse(cityIn, cityIn)
|
||||
val district = if (districtIn == null || districtIn.equals("未知")) "" else districtNameMap.getOrElse(districtIn, districtIn)
|
||||
val street = if (streetIn == null || streetIn.equals("未知")) "" else streetIn
|
||||
|
||||
val provinceAd = adminData.values.filter(s => s.level.equals(DistrictLevel.Province)).filter(s => StringUtils.isEmpty(province) || s.name.equals(province) || (!isFullMatch && s.shortName.equals(province)))
|
||||
@ -142,7 +157,7 @@ private[lnglat2Geo] object GeoTransImpl {
|
||||
Admin.createStreet(province.name, city.name, district.name, admin.name, province.id, city.id, district.id, admin.id, admin.center)
|
||||
case _ => Admin.createOversea
|
||||
}
|
||||
}).toSeq
|
||||
}).toList
|
||||
}
|
||||
|
||||
private def determineAdminCode(lonIn: Double, latIn: Double, coordSys: CoordinateSystem = CoordinateSystem.GCJ02): Int = {
|
||||
@ -161,7 +176,7 @@ private[lnglat2Geo] object GeoTransImpl {
|
||||
boundaryAdminCell.getOrElse(id2, -1)
|
||||
} else {
|
||||
var keys = List.empty[Long]
|
||||
var maxLevel = 2000 //必须大于2000m,否则会出现格子半径过小选择错误问题
|
||||
var maxLevel = 2000 //必须大于2000m,否则会出现格子半径过小选择错误问题
|
||||
|
||||
// 最远距离 为新疆哈密市80公里
|
||||
while (keys.isEmpty && maxLevel < 200000) {
|
||||
@ -174,7 +189,7 @@ private[lnglat2Geo] object GeoTransImpl {
|
||||
.map(key => (key, new S2CellId(key).toLatLng.getEarthDistance(s2LatLng)))
|
||||
.sortBy(_._2)
|
||||
.take(5)
|
||||
.flatMap(startPoint => boundaryData.getOrElse(startPoint._1, List.empty).map(value => (startPoint._1, value._1, value._2, value._3)))
|
||||
.flatMap(startPoint => boundaryData.getOrElse(startPoint._1, List.empty).flatMap(value => List((startPoint._1, value._1, value._2, true), (startPoint._1, value._1, value._3, false))))
|
||||
.map(line => {
|
||||
val start = new S2CellId(line._1).toLatLng
|
||||
val end = new S2CellId(line._2).toLatLng
|
||||
@ -238,7 +253,7 @@ private[lnglat2Geo] object GeoTransImpl {
|
||||
}
|
||||
|
||||
def determineAreaByAdmin(lon: Double, lat: Double, admin: Admin, radius: Int): BusinessAreaInfo = {
|
||||
val businessAreas = determineAreaByCityId(lon, lat, admin.cityID, radius, CoordinateSystem.GCJ02)
|
||||
val businessAreas = determineAreaByCityId(lon, lat, admin.cityCode, radius, CoordinateSystem.GCJ02)
|
||||
BusinessAreaInfo(admin, businessAreas)
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,8 @@ package com.dengxq.lnglat2Geo.build
|
||||
|
||||
import com.dengxq.lnglat2Geo.entity.{AdminBoundary, AdminNode, CellAdmin}
|
||||
import com.dengxq.lnglat2Geo.utils.ObjectSerializer
|
||||
import com.google.common.geometry._
|
||||
import scala.collection.JavaConverters._
|
||||
import org.json4s.DefaultFormats
|
||||
import org.json4s.jackson.JsonMethods.parse
|
||||
|
||||
@ -11,6 +13,8 @@ import scala.util.Try
|
||||
object AdminDataProvider {
|
||||
|
||||
final val CHINA_DISTRICT_BOUNDARY = "src/main/resources/china/boundary.data"
|
||||
final val CHINA_DISTRICT_BOUNDARY2 = "data/china/boundary.data"
|
||||
final val CHINA_DISTRICT_BOUNDARY3 = "data/china/boundary3.data"
|
||||
final val RESOURCE_CHINA_DISTRICT_BOUNDARY = "/china/boundary.data"
|
||||
|
||||
final val CHINA_DISTRICT_BOUNDARY_CELL = "src/main/resources/china/boundaryCell.data"
|
||||
@ -43,6 +47,45 @@ object AdminDataProvider {
|
||||
Option(data)
|
||||
}.getOrElse(None)
|
||||
}
|
||||
|
||||
private def loadS2CellUnion(polylineString: String, minLevel: Int = -1, maxLevel: Int = -1, maxCells: Int = -1)
|
||||
: S2CellUnion = {
|
||||
val s2PolygonBuilder = new S2PolygonBuilder()
|
||||
|
||||
// polyline 中 | 分割多个polygon, 每个polygon的点用 ; 分割.
|
||||
// 每个 polygon 构建 一个 S2Loop, 合并到 S2PolygonBuilder中生成 multi polygon
|
||||
polylineString.split('|').foreach(loopStr => {
|
||||
val points: Array[S2Point] = loopStr.split(';').map(coordStr => {
|
||||
val parts = coordStr.split(',')
|
||||
// (parts(0).toDouble, parts(1).toDouble)
|
||||
val lng = parts(0).toDouble
|
||||
val lat = parts(1).toDouble
|
||||
S2LatLng.fromDegrees(lat, lng).toPoint
|
||||
})
|
||||
val jPoints = points.toList.asJava
|
||||
|
||||
s2PolygonBuilder.addLoop(new S2Loop(jPoints))
|
||||
})
|
||||
|
||||
val polygon = s2PolygonBuilder.assemblePolygon()
|
||||
|
||||
// 栅格化处理区域多边形
|
||||
val coverer = new S2RegionCoverer()
|
||||
if (minLevel > 0) {
|
||||
coverer.setMinLevel(minLevel)
|
||||
}
|
||||
if (maxLevel > 0) {
|
||||
coverer.setMaxLevel(maxLevel)
|
||||
}
|
||||
if (maxCells > 0) {
|
||||
coverer.setMaxCells(maxCells)
|
||||
}
|
||||
|
||||
//val s2CellUnion = coverer.getInteriorCovering(polygon)
|
||||
val s2CellUnion = coverer.getCovering(polygon)
|
||||
s2CellUnion.normalize()
|
||||
s2CellUnion
|
||||
}
|
||||
}
|
||||
|
||||
object AdminLoader {
|
||||
@ -59,7 +102,7 @@ object AdminDataProvider {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def loadBoundaryData: Map[Long, List[(Long, Int, Boolean)]] = {
|
||||
def loadBoundaryData: Map[Long, List[(Long, Int, Int)]] = {
|
||||
val stream = this.getClass.getResourceAsStream(RESOURCE_CHINA_DISTRICT_BOUNDARY)
|
||||
ObjectSerializer
|
||||
.deserialize[Array[AdminBoundary]](stream)
|
||||
@ -69,7 +112,21 @@ object AdminDataProvider {
|
||||
))
|
||||
.toList
|
||||
.groupBy(_._1)
|
||||
.map(s => (s._1, s._2.map(ss => (ss._2, ss._3, ss._4))))
|
||||
.map(s => (s._1, s._2.map(ss => (ss._2, ss._3, ss._4)).groupBy(_._1)
|
||||
.map(sss => {
|
||||
val list = sss._2.map(ssss => (ssss._2, ssss._3)).sortBy(_._2)(Ordering.Boolean.reverse)
|
||||
if (list.size > 2) throw new Exception
|
||||
else if (list.size == 2) {
|
||||
if (!list.head._2 || list.last._2) throw new Exception
|
||||
val first = list.head._1
|
||||
val second = list.last._1
|
||||
(sss._1, first, second)
|
||||
} else {
|
||||
if (list.head._2) (sss._1, list.head._1, -1)
|
||||
else (sss._1, -1, list.head._1)
|
||||
}
|
||||
}).toList
|
||||
))
|
||||
}
|
||||
|
||||
def loadBoundaryCellData: Map[Long, Int] = {
|
||||
|
@ -11,6 +11,7 @@ import com.dengxq.lnglat2Geo.utils.S2Utils.{childrenCellId, getLevel}
|
||||
import com.dengxq.lnglat2Geo.GeoTransImpl.min_level
|
||||
import AdminDataProvider._
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import collection.JavaConversions._
|
||||
|
||||
object Upgrade {
|
||||
@ -76,6 +77,53 @@ object Upgrade {
|
||||
})
|
||||
}
|
||||
|
||||
def loadBoundary2(): Array[AdminBoundary2] = {
|
||||
DistrictLoader.loadAMapJson("country/" + 100000 + ".json")
|
||||
.get
|
||||
.districts
|
||||
.flatMap(province => {
|
||||
val provinceData = DistrictLoader.loadAMapJson("province/" + province.adcode + ".json")
|
||||
if (provinceData.nonEmpty) {
|
||||
val cityDatas = provinceData.get
|
||||
.districts
|
||||
.flatMap(city => {
|
||||
val cityData = DistrictLoader.loadAMapJson("city/" + city.adcode + ".json")
|
||||
if (cityData.nonEmpty) {
|
||||
val districtDatas = cityData.get.districts.map(dis => DistrictLoader.loadAMapJson("district/" + dis.adcode + ".json"))
|
||||
if (districtDatas.exists(s => s.nonEmpty && s.get.polyline.nonEmpty)) districtDatas
|
||||
else List(cityData)
|
||||
} else {
|
||||
val districtData = DistrictLoader.loadAMapJson("district/" + city.adcode + ".json")
|
||||
if (districtData.nonEmpty && districtData.get.polyline.nonEmpty) List(districtData)
|
||||
else List.empty
|
||||
}
|
||||
})
|
||||
if (cityDatas.exists(s => s.nonEmpty && s.get.polyline.nonEmpty)) cityDatas
|
||||
else List(provinceData)
|
||||
} else List.empty
|
||||
})
|
||||
.filter(_.nonEmpty)
|
||||
.flatMap(district => {
|
||||
if (district.get.polyline.nonEmpty) {
|
||||
val data = district.get.polyline.get.split('|').map(loopStr => {
|
||||
loopStr.split(';')
|
||||
.map(coordStr => {
|
||||
val parts = coordStr.split(',')
|
||||
(parts(0).toDouble, parts(1).toDouble)
|
||||
})
|
||||
})
|
||||
|
||||
val points = data.flatMap(_.toList)
|
||||
val mbr = (points.map(_._1).min, points.map(_._1).max, points.map(_._2).min, points.map(_._2).max)
|
||||
|
||||
val boundary = data.map(s => s.map(ss => S2CellId.fromLatLng(S2LatLng.fromDegrees(ss._2, ss._1)).id()))
|
||||
|
||||
List(AdminBoundary2(district.get.adcode.toInt, mbr, boundary))
|
||||
}
|
||||
else List.empty
|
||||
})
|
||||
}
|
||||
|
||||
def genCellAdmin(): Array[CellAdmin] = {
|
||||
|
||||
// 国内区县边界S2块
|
||||
@ -222,6 +270,12 @@ object Upgrade {
|
||||
}
|
||||
}
|
||||
|
||||
def upgradeAdminBoundary2(): Unit = {
|
||||
val data = loadBoundary2()
|
||||
ObjectSerializer.serialize(data, Paths.get(CHINA_DISTRICT_BOUNDARY2).toAbsolutePath.toString)
|
||||
}
|
||||
|
||||
|
||||
def upgradeAdminBoundary(): Unit = {
|
||||
val data = loadBoundary()
|
||||
ObjectSerializer.serialize(data, Paths.get(CHINA_DISTRICT_BOUNDARY).toAbsolutePath.toString)
|
||||
@ -247,11 +301,97 @@ object Upgrade {
|
||||
ObjectSerializer.serialize(obj, Paths.get(CityAreaDataProvider.BUSINESS_AREA_DATA).toAbsolutePath.toString)
|
||||
}
|
||||
|
||||
def loadSharedLines(boundary: Array[AdminBoundary2]): Array[AdminCommonBoundary] = {
|
||||
var result = ArrayBuffer.empty[AdminCommonBoundary]
|
||||
for (i <- 0 until boundary.length - 1) {
|
||||
val admin1 = boundary(i)
|
||||
val bound1 = admin1.mbr
|
||||
println(i, admin1.code)
|
||||
for (j <- i + 1 until boundary.length) {
|
||||
val admin2 = boundary(j)
|
||||
val bound2 = admin2.mbr
|
||||
|
||||
val pair = if (bound1._1 > bound2._2 || bound2._1 > bound1._2 || bound1._3 > bound2._4 || bound2._3 > bound1._4) Array.empty[AdminCommonBoundary]
|
||||
else admin1.boundary.flatMap(line1 => {
|
||||
val line1Index = line1.zipWithIndex.toMap
|
||||
|
||||
val commons = admin2.boundary.flatMap(line2 =>
|
||||
line2.zipWithIndex
|
||||
.filter(s => line1.contains(s._1))
|
||||
.map(s => {
|
||||
val index1 = line1Index.getOrElse(s._1, 0)
|
||||
(s._1, s._2, index1, s._2 + index1)
|
||||
})
|
||||
.groupBy(_._4)
|
||||
.map(s => (admin2.code, admin1.code, s._2.sortBy(_._2))) // 线段方向是admin2的
|
||||
)
|
||||
|
||||
if (commons.nonEmpty) commons.map(s => AdminCommonBoundary(s._1, s._2, s._3.map(_._1)))
|
||||
else List.empty
|
||||
})
|
||||
result = result ++ pair
|
||||
}
|
||||
}
|
||||
result.toArray
|
||||
}
|
||||
|
||||
def loadOnesideLine(sharedLines: Array[AdminCommonBoundary], boundary: Array[AdminBoundary2]): Array[AdminCommonBoundary] = {
|
||||
val commons = sharedLines
|
||||
.flatMap(s => List((s.code, s.boundary), (s.code2, s.boundary)))
|
||||
.groupBy(_._1)
|
||||
.map(s => (s._1, s._2.flatMap(_._2.toList)))
|
||||
|
||||
boundary.flatMap(s => {
|
||||
val common: Array[Long] = commons.getOrElse(s.code, Array.empty)
|
||||
val result = ArrayBuffer.empty[ArrayBuffer[Long]]
|
||||
|
||||
s.boundary.foreach(ss => {
|
||||
var temp = ArrayBuffer.empty[Long]
|
||||
|
||||
ss.foreach(sss => {
|
||||
if (common.isEmpty || !common.contains(sss)) temp.append(sss)
|
||||
else if (temp.nonEmpty) {
|
||||
result.append(temp)
|
||||
temp = ArrayBuffer.empty[Long]
|
||||
}
|
||||
})
|
||||
if (temp.nonEmpty) result.append(temp)
|
||||
})
|
||||
|
||||
if (result.nonEmpty) {
|
||||
println("code = " + s.code)
|
||||
val sssss = result.map(s => s.map(s => {
|
||||
val latlng = new S2CellId(s).toLatLng
|
||||
List(latlng.lngDegrees(), latlng.latDegrees()).mkString(",")
|
||||
})).mkString(";")
|
||||
println(sssss)
|
||||
result.map(ss => AdminCommonBoundary(s.code, -1, ss.toArray))
|
||||
}
|
||||
else List.empty
|
||||
})
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
Upgrade.upgradeAdminBoundary() // 生成行政区划边界数据
|
||||
Upgrade.upgradeAdminBoundaryCell() // 生成行政区划边界数据2
|
||||
Upgrade.upgradeChinaAdmin() // 生成行政区划关系数据(不含街道)
|
||||
Upgrade.upgradeTownship() // 生成行政区划街道数据
|
||||
Upgrade.upgradeBusinessAreaData() // 生成商圈数据
|
||||
// upgradeAdminBoundary2()
|
||||
|
||||
Upgrade.upgradeAdminBoundary() // 生成行政区划边界数据
|
||||
Upgrade.upgradeAdminBoundaryCell() // 生成行政区划边界数据2
|
||||
Upgrade.upgradeChinaAdmin() // 生成行政区划关系数据(不含街道)
|
||||
Upgrade.upgradeTownship() // 生成行政区划街道数据
|
||||
Upgrade.upgradeBusinessAreaData() // 生成商圈数据
|
||||
|
||||
// val data = loadBoundary2()
|
||||
//
|
||||
// val sharedLines = loadSharedLines(data)
|
||||
// val oneSide: Array[AdminCommonBoundary] = loadOnesideLine(sharedLines, data)
|
||||
|
||||
// ObjectSerializer.serialize(result.toArray, Paths.get(CHINA_DISTRICT_BOUNDARY2).toAbsolutePath.toString)
|
||||
// ObjectSerializer.serialize(oneSide, Paths.get(CHINA_DISTRICT_BOUNDARY3).toAbsolutePath.toString)
|
||||
|
||||
// val stream = this.getClass.getResourceAsStream(RESOURCE_CHINA_DISTRICT_BOUNDARY)
|
||||
// ObjectSerializer
|
||||
// .deserialize[Array[AdminCommonBoundary]](stream)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
package com.dengxq.lnglat2Geo.entity
|
||||
|
||||
import com.dengxq.lnglat2Geo.entity.AdminLevel.AdminLevel
|
||||
import com.dengxq.lnglat2Geo.utils.AdminUtils
|
||||
|
||||
case class Admin(country: String,
|
||||
province: String,
|
||||
city: String,
|
||||
district: String,
|
||||
street: String,
|
||||
level: AdminLevel,
|
||||
countryID: String,
|
||||
provinceID: Int,
|
||||
cityID: Int,
|
||||
districtID: Int,
|
||||
streetID: Int,
|
||||
town: String,
|
||||
level: String,
|
||||
countryCode: String,
|
||||
provinceCode: Int,
|
||||
cityCode: Int,
|
||||
districtCode: Int,
|
||||
townCode: Int,
|
||||
center: Location = null
|
||||
) {
|
||||
|
||||
@ -21,21 +20,21 @@ case class Admin(country: String,
|
||||
def hasProvince: Boolean = province != Admin.UNKNOWN_NAME_VAL
|
||||
def hasCity: Boolean = city != Admin.UNKNOWN_NAME_VAL
|
||||
def hasDistrict: Boolean = district != Admin.UNKNOWN_NAME_VAL
|
||||
def hasCityId: Boolean = cityID != Admin.UNKNOWN_ID_VAL
|
||||
def hasDistrictId: Boolean = districtID != Admin.UNKNOWN_ID_VAL
|
||||
def hasStreet: Boolean = street != Admin.UNKNOWN_NAME_VAL
|
||||
def hasCityId: Boolean = cityCode != Admin.UNKNOWN_ID_VAL
|
||||
def hasDistrictId: Boolean = districtCode != Admin.UNKNOWN_ID_VAL
|
||||
def hasTown: Boolean = town != Admin.UNKNOWN_NAME_VAL
|
||||
def shortProvince :String = AdminUtils.shortProvince(province)
|
||||
def shortCity :String = AdminUtils.shortCity(city)
|
||||
def toShort: Admin = Admin(country,
|
||||
AdminUtils.shortProvince(province),
|
||||
AdminUtils.shortCity(city),
|
||||
AdminUtils.shortDistrict(district),
|
||||
AdminUtils.shortStreet(street),
|
||||
level, countryID, provinceID, cityID, districtID, streetID, center)
|
||||
def toNameString: String = s"$country${if(hasProvince) province else ""}${if(hasCity) city else ""}${if(hasDistrict) district else ""}${if(hasStreet) street else ""}"
|
||||
AdminUtils.shortStreet(town),
|
||||
level, countryCode, provinceCode, cityCode, districtCode, townCode, center)
|
||||
def toNameString: String = s"$country${if(hasProvince) province else ""}${if(hasCity) city else ""}${if(hasDistrict) district else ""}${if(hasTown) town else ""}"
|
||||
}
|
||||
|
||||
object Admin {
|
||||
private[lnglat2Geo] object Admin {
|
||||
private final val CHINA_NAME = "中国"
|
||||
private final val CHINA_ID = "CN"
|
||||
private final val OVERSEA_NAME_VAL = "海外"
|
||||
@ -43,109 +42,109 @@ object Admin {
|
||||
private final val UNKNOWN_ID_VAL = -1
|
||||
private final val UNKNOWN_LOCATION_VAL = null
|
||||
|
||||
private[lnglat2Geo] def createOversea = Admin(OVERSEA_NAME_VAL,
|
||||
def createOversea = Admin(OVERSEA_NAME_VAL,
|
||||
province = OVERSEA_NAME_VAL,
|
||||
city = OVERSEA_NAME_VAL,
|
||||
district = OVERSEA_NAME_VAL,
|
||||
street = OVERSEA_NAME_VAL,
|
||||
town = OVERSEA_NAME_VAL,
|
||||
level = AdminLevel.Oversea,
|
||||
countryID = "",
|
||||
provinceID = UNKNOWN_ID_VAL,
|
||||
cityID = UNKNOWN_ID_VAL,
|
||||
districtID = UNKNOWN_ID_VAL,
|
||||
streetID = UNKNOWN_ID_VAL,
|
||||
countryCode = "",
|
||||
provinceCode = UNKNOWN_ID_VAL,
|
||||
cityCode = UNKNOWN_ID_VAL,
|
||||
districtCode = UNKNOWN_ID_VAL,
|
||||
townCode = UNKNOWN_ID_VAL,
|
||||
center = UNKNOWN_LOCATION_VAL
|
||||
)
|
||||
|
||||
private[lnglat2Geo] def createCountry(country:String, countryID:String, center: Location) = Admin(
|
||||
def createCountry(country:String, countryID:String, center: Location) = Admin(
|
||||
country,
|
||||
province = UNKNOWN_NAME_VAL,
|
||||
city = UNKNOWN_NAME_VAL,
|
||||
district = UNKNOWN_NAME_VAL,
|
||||
street = UNKNOWN_NAME_VAL,
|
||||
town = UNKNOWN_NAME_VAL,
|
||||
level = AdminLevel.Country,
|
||||
countryID = countryID,
|
||||
provinceID = UNKNOWN_ID_VAL,
|
||||
cityID = UNKNOWN_ID_VAL,
|
||||
districtID = UNKNOWN_ID_VAL,
|
||||
streetID = UNKNOWN_ID_VAL,
|
||||
countryCode = countryID,
|
||||
provinceCode = UNKNOWN_ID_VAL,
|
||||
cityCode = UNKNOWN_ID_VAL,
|
||||
districtCode = UNKNOWN_ID_VAL,
|
||||
townCode = UNKNOWN_ID_VAL,
|
||||
center = center
|
||||
)
|
||||
|
||||
private[lnglat2Geo] def createProvince(province: String, provinceId: Int, center: Location) = Admin(
|
||||
def createProvince(province: String, provinceId: Int, center: Location) = Admin(
|
||||
country = CHINA_NAME,
|
||||
province = province,
|
||||
city = UNKNOWN_NAME_VAL,
|
||||
district = UNKNOWN_NAME_VAL,
|
||||
street = UNKNOWN_NAME_VAL,
|
||||
town = UNKNOWN_NAME_VAL,
|
||||
level = AdminLevel.Province,
|
||||
countryID = CHINA_ID,
|
||||
provinceID = provinceId,
|
||||
cityID = UNKNOWN_ID_VAL,
|
||||
districtID = UNKNOWN_ID_VAL,
|
||||
streetID = UNKNOWN_ID_VAL,
|
||||
countryCode = CHINA_ID,
|
||||
provinceCode = provinceId,
|
||||
cityCode = UNKNOWN_ID_VAL,
|
||||
districtCode = UNKNOWN_ID_VAL,
|
||||
townCode = UNKNOWN_ID_VAL,
|
||||
center = center
|
||||
)
|
||||
|
||||
private[lnglat2Geo] def createCity(province: String, city: String, provinceId: Int, cityId: Int, center: Location) = Admin(
|
||||
def createCity(province: String, city: String, provinceId: Int, cityId: Int, center: Location) = Admin(
|
||||
country = CHINA_NAME,
|
||||
province = province,
|
||||
city = city,
|
||||
district = UNKNOWN_NAME_VAL,
|
||||
street = UNKNOWN_NAME_VAL,
|
||||
town = UNKNOWN_NAME_VAL,
|
||||
level = AdminLevel.City,
|
||||
countryID = CHINA_ID,
|
||||
provinceID = provinceId,
|
||||
cityID = cityId,
|
||||
districtID = UNKNOWN_ID_VAL,
|
||||
streetID = UNKNOWN_ID_VAL,
|
||||
countryCode = CHINA_ID,
|
||||
provinceCode = provinceId,
|
||||
cityCode = cityId,
|
||||
districtCode = UNKNOWN_ID_VAL,
|
||||
townCode = UNKNOWN_ID_VAL,
|
||||
center = center
|
||||
)
|
||||
|
||||
private[lnglat2Geo] def createProvincialCity(province: String, city: String, provinceId: Int, cityId: Int, center: Location) = Admin(
|
||||
def createProvincialCity(province: String, city: String, provinceId: Int, cityId: Int, center: Location) = Admin(
|
||||
country = CHINA_NAME,
|
||||
province = province,
|
||||
city = city,
|
||||
district = city,
|
||||
street = UNKNOWN_NAME_VAL,
|
||||
town = UNKNOWN_NAME_VAL,
|
||||
level = AdminLevel.ProvincialCity,
|
||||
countryID = CHINA_ID,
|
||||
provinceID = provinceId,
|
||||
cityID = cityId,
|
||||
districtID = cityId,
|
||||
streetID = UNKNOWN_ID_VAL,
|
||||
countryCode = CHINA_ID,
|
||||
provinceCode = provinceId,
|
||||
cityCode = cityId,
|
||||
districtCode = cityId,
|
||||
townCode = UNKNOWN_ID_VAL,
|
||||
center = center
|
||||
)
|
||||
|
||||
private[lnglat2Geo] def createDistrict(province: String, city: String, district: String,
|
||||
def createDistrict(province: String, city: String, district: String,
|
||||
provinceId:Int, cityId: Int, districtId: Int, center: Location) = Admin(
|
||||
country = CHINA_NAME,
|
||||
province = province,
|
||||
city = city,
|
||||
district = district,
|
||||
street = UNKNOWN_NAME_VAL,
|
||||
town = UNKNOWN_NAME_VAL,
|
||||
level = AdminLevel.District,
|
||||
countryID = CHINA_ID,
|
||||
provinceID = provinceId,
|
||||
cityID = cityId,
|
||||
districtID = districtId,
|
||||
streetID = UNKNOWN_ID_VAL,
|
||||
countryCode = CHINA_ID,
|
||||
provinceCode = provinceId,
|
||||
cityCode = cityId,
|
||||
districtCode = districtId,
|
||||
townCode = UNKNOWN_ID_VAL,
|
||||
center = center
|
||||
)
|
||||
|
||||
private[lnglat2Geo] def createStreet(province: String, city: String, district: String, street: String,
|
||||
def createStreet(province: String, city: String, district: String, town: String,
|
||||
provinceId:Int, cityId: Int, districtId: Int, streetId: Int, center: Location) = Admin(
|
||||
country = CHINA_NAME,
|
||||
province = province,
|
||||
city = city,
|
||||
district = district,
|
||||
street = street,
|
||||
town = town,
|
||||
level = AdminLevel.Street,
|
||||
countryID = CHINA_ID,
|
||||
provinceID = provinceId,
|
||||
cityID = cityId,
|
||||
districtID = districtId,
|
||||
streetID = streetId,
|
||||
countryCode = CHINA_ID,
|
||||
provinceCode = provinceId,
|
||||
cityCode = cityId,
|
||||
districtCode = districtId,
|
||||
townCode = streetId,
|
||||
center = center
|
||||
)
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
package com.dengxq.lnglat2Geo.entity
|
||||
|
||||
@SerialVersionUID(-1l)
|
||||
case class AdminBoundary2(var code: Int, var mbr: (Double, Double, Double, Double), var boundary: Array[Array[Long]]) extends Serializable
|
@ -0,0 +1,4 @@
|
||||
package com.dengxq.lnglat2Geo.entity
|
||||
|
||||
@SerialVersionUID(-1)
|
||||
case class AdminCommonBoundary(var code:Int, var code2:Int, var boundary : Array[Long]) extends Serializable
|
@ -54,20 +54,19 @@ object DistrictLevel extends EnumFunc {
|
||||
}
|
||||
|
||||
@SerialVersionUID(568714356783645678L)
|
||||
object AdminLevel extends EnumFunc {
|
||||
type AdminLevel = Value
|
||||
object AdminLevel {
|
||||
/**海外**/
|
||||
val Oversea = Value("oversea")
|
||||
val Oversea = "oversea"
|
||||
/**国家**/
|
||||
val Country = Value("country")
|
||||
val Country = "country"
|
||||
/**省,自治区**/
|
||||
val Province = Value("province")
|
||||
val Province = "province"
|
||||
/**地级市**/
|
||||
val City = Value("city")
|
||||
val City = "city"
|
||||
/**省辖市(属县级市) see:https://baike.baidu.com/item/省直辖县级行政单位**/
|
||||
val ProvincialCity = Value("provincialcity")
|
||||
val ProvincialCity = "provincialcity"
|
||||
/**区,县,县级市**/
|
||||
val District = Value("district")
|
||||
val District = "district"
|
||||
/**街道**/
|
||||
val Street = Value("street")
|
||||
val Street = "street"
|
||||
}
|
@ -12,7 +12,7 @@ object Func {
|
||||
class _sm(streetMap: StreetMap) {
|
||||
def findNearStreet(districtAdmin: Admin, lonlat: (Double, Double)) :Option[StreetNode] = {
|
||||
val loc = Location(lonlat._1, lonlat._2)
|
||||
val districtId = if(districtAdmin.districtID != -1) districtAdmin.districtID else districtAdmin.cityID
|
||||
val districtId = if(districtAdmin.districtCode != -1) districtAdmin.districtCode else districtAdmin.cityCode
|
||||
if(streetMap.data.contains(districtId)) {
|
||||
val streetDistanceLs = streetMap.data(districtId)
|
||||
.flatMap { sn =>
|
||||
|
Loading…
Reference in New Issue
Block a user