优化内存

This commit is contained in:
dengxingqi [邓兴启] 2019-10-11 15:12:44 +08:00
parent b206c870fd
commit f60a0d5474
10 changed files with 319 additions and 100 deletions

View File

@ -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>

View File

@ -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)
}
/**

View File

@ -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)
}

View File

@ -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] = {

View File

@ -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)
}
}

View File

@ -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
)

View File

@ -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

View File

@ -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

View File

@ -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"
}

View File

@ -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 =>