DESKTOP-6LTVLN7\Liumouren vor 8 Monaten
Commit
c65d1bc7a7
30 geänderte Dateien mit 3675 neuen und 0 gelöschten Zeilen
  1. 2 0
      .gitattributes
  2. 33 0
      .gitignore
  3. 19 0
      .mvn/wrapper/maven-wrapper.properties
  4. BIN
      doc/marge_excel_uuid-1.xlsx
  5. BIN
      doc/marge_excel_uuid-2.xlsx
  6. BIN
      doc/outPutTableHeader.xlsx
  7. 0 0
      doc/park_express_spread.geojson
  8. BIN
      doc/tableHeader.xlsx
  9. 0 0
      doc/青浦区边界.geojson
  10. 259 0
      mvnw
  11. 149 0
      mvnw.cmd
  12. 179 0
      pom.xml
  13. 13 0
      src/main/java/com/example/poiaddr/PoiAddrApplication.java
  14. 266 0
      src/main/java/com/example/poiaddr/controller/PoiAddressController.java
  15. 11 0
      src/main/java/com/example/poiaddr/dao/PoiAddressRepository.java
  16. 163 0
      src/main/java/com/example/poiaddr/entity/PoiAddress.java
  17. 12 0
      src/main/java/com/example/poiaddr/service/PoiAddressService.java
  18. 49 0
      src/main/java/com/example/poiaddr/service/impl/PoiAddressServiceImpl.java
  19. 742 0
      src/main/java/com/example/poiaddr/util/CoordTransform.java
  20. 346 0
      src/main/java/com/example/poiaddr/util/Coordinate.java
  21. 472 0
      src/main/java/com/example/poiaddr/util/ExcelReaderUtils.java
  22. 88 0
      src/main/java/com/example/poiaddr/util/RequestUtils.java
  23. 294 0
      src/main/java/com/example/poiaddr/util/ZipUnit/CompressUtil.java
  24. 21 0
      src/main/java/com/example/poiaddr/util/ZipUnit/FileInfo.java
  25. 46 0
      src/main/java/com/example/poiaddr/util/dms/login.java
  26. 388 0
      src/main/java/com/example/poiaddr/util/geotools/GeoHelpScript.java
  27. 41 0
      src/main/java/com/example/poiaddr/util/geotools/GeoJsonPointInRegion.java
  28. 56 0
      src/main/java/com/example/poiaddr/util/geotools/GeometryIntersectionAndDisjoint.java
  29. 13 0
      src/main/resources/application.properties
  30. 13 0
      src/test/java/com/example/poiaddr/PoiAddrApplicationTests.java

+ 2 - 0
.gitattributes

@@ -0,0 +1,2 @@
+/mvnw text eol=lf
+*.cmd text eol=crlf

+ 33 - 0
.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 19 - 0
.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+wrapperVersion=3.3.2
+distributionType=only-script
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip

BIN
doc/marge_excel_uuid-1.xlsx


BIN
doc/marge_excel_uuid-2.xlsx


BIN
doc/outPutTableHeader.xlsx


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
doc/park_express_spread.geojson


BIN
doc/tableHeader.xlsx


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
doc/青浦区边界.geojson


+ 259 - 0
mvnw

@@ -0,0 +1,259 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.3.2
+#
+# Optional ENV vars
+# -----------------
+#   JAVA_HOME - location of a JDK home dir, required when download maven via java source
+#   MVNW_REPOURL - repo url base for downloading maven distribution
+#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
+# ----------------------------------------------------------------------------
+
+set -euf
+[ "${MVNW_VERBOSE-}" != debug ] || set -x
+
+# OS specific support.
+native_path() { printf %s\\n "$1"; }
+case "$(uname)" in
+CYGWIN* | MINGW*)
+  [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
+  native_path() { cygpath --path --windows "$1"; }
+  ;;
+esac
+
+# set JAVACMD and JAVACCMD
+set_java_home() {
+  # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
+  if [ -n "${JAVA_HOME-}" ]; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+      JAVACCMD="$JAVA_HOME/jre/sh/javac"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+      JAVACCMD="$JAVA_HOME/bin/javac"
+
+      if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
+        echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
+        echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
+        return 1
+      fi
+    fi
+  else
+    JAVACMD="$(
+      'set' +e
+      'unset' -f command 2>/dev/null
+      'command' -v java
+    )" || :
+    JAVACCMD="$(
+      'set' +e
+      'unset' -f command 2>/dev/null
+      'command' -v javac
+    )" || :
+
+    if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
+      echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
+      return 1
+    fi
+  fi
+}
+
+# hash string like Java String::hashCode
+hash_string() {
+  str="${1:-}" h=0
+  while [ -n "$str" ]; do
+    char="${str%"${str#?}"}"
+    h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
+    str="${str#?}"
+  done
+  printf %x\\n $h
+}
+
+verbose() { :; }
+[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
+
+die() {
+  printf %s\\n "$1" >&2
+  exit 1
+}
+
+trim() {
+  # MWRAPPER-139:
+  #   Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
+  #   Needed for removing poorly interpreted newline sequences when running in more
+  #   exotic environments such as mingw bash on Windows.
+  printf "%s" "${1}" | tr -d '[:space:]'
+}
+
+# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
+while IFS="=" read -r key value; do
+  case "${key-}" in
+  distributionUrl) distributionUrl=$(trim "${value-}") ;;
+  distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
+  esac
+done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
+[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
+
+case "${distributionUrl##*/}" in
+maven-mvnd-*bin.*)
+  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
+  case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
+  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
+  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
+  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
+  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
+  *)
+    echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
+    distributionPlatform=linux-amd64
+    ;;
+  esac
+  distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
+  ;;
+maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
+*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
+esac
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
+[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
+distributionUrlName="${distributionUrl##*/}"
+distributionUrlNameMain="${distributionUrlName%.*}"
+distributionUrlNameMain="${distributionUrlNameMain%-bin}"
+MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
+MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
+
+exec_maven() {
+  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
+  exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
+}
+
+if [ -d "$MAVEN_HOME" ]; then
+  verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+  exec_maven "$@"
+fi
+
+case "${distributionUrl-}" in
+*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
+*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
+esac
+
+# prepare tmp dir
+if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
+  clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
+  trap clean HUP INT TERM EXIT
+else
+  die "cannot create temp dir"
+fi
+
+mkdir -p -- "${MAVEN_HOME%/*}"
+
+# Download and Install Apache Maven
+verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+verbose "Downloading from: $distributionUrl"
+verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+# select .zip or .tar.gz
+if ! command -v unzip >/dev/null; then
+  distributionUrl="${distributionUrl%.zip}.tar.gz"
+  distributionUrlName="${distributionUrl##*/}"
+fi
+
+# verbose opt
+__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
+[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
+
+# normalize http auth
+case "${MVNW_PASSWORD:+has-password}" in
+'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
+esac
+
+if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
+  verbose "Found wget ... using wget"
+  wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
+elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
+  verbose "Found curl ... using curl"
+  curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
+elif set_java_home; then
+  verbose "Falling back to use Java to download"
+  javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
+  targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
+  cat >"$javaSource" <<-END
+	public class Downloader extends java.net.Authenticator
+	{
+	  protected java.net.PasswordAuthentication getPasswordAuthentication()
+	  {
+	    return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
+	  }
+	  public static void main( String[] args ) throws Exception
+	  {
+	    setDefault( new Downloader() );
+	    java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
+	  }
+	}
+	END
+  # For Cygwin/MinGW, switch paths to Windows format before running javac and java
+  verbose " - Compiling Downloader.java ..."
+  "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
+  verbose " - Running Downloader.java ..."
+  "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
+fi
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+if [ -n "${distributionSha256Sum-}" ]; then
+  distributionSha256Result=false
+  if [ "$MVN_CMD" = mvnd.sh ]; then
+    echo "Checksum validation is not supported for maven-mvnd." >&2
+    echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+    exit 1
+  elif command -v sha256sum >/dev/null; then
+    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
+      distributionSha256Result=true
+    fi
+  elif command -v shasum >/dev/null; then
+    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
+      distributionSha256Result=true
+    fi
+  else
+    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
+    echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
+    exit 1
+  fi
+  if [ $distributionSha256Result = false ]; then
+    echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
+    echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
+    exit 1
+  fi
+fi
+
+# unzip and move
+if command -v unzip >/dev/null; then
+  unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
+else
+  tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
+fi
+printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
+mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
+
+clean || :
+exec_maven "$@"

+ 149 - 0
mvnw.cmd

@@ -0,0 +1,149 @@
+<# : batch portion
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.3.2
+@REM
+@REM Optional ENV vars
+@REM   MVNW_REPOURL - repo url base for downloading maven distribution
+@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
+@REM ----------------------------------------------------------------------------
+
+@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
+@SET __MVNW_CMD__=
+@SET __MVNW_ERROR__=
+@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
+@SET PSModulePath=
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
+  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
+)
+@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
+@SET __MVNW_PSMODULEP_SAVE=
+@SET __MVNW_ARG0_NAME__=
+@SET MVNW_USERNAME=
+@SET MVNW_PASSWORD=
+@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
+@echo Cannot start maven from wrapper >&2 && exit /b 1
+@GOTO :EOF
+: end batch / begin powershell #>
+
+$ErrorActionPreference = "Stop"
+if ($env:MVNW_VERBOSE -eq "true") {
+  $VerbosePreference = "Continue"
+}
+
+# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
+$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
+if (!$distributionUrl) {
+  Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
+}
+
+switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
+  "maven-mvnd-*" {
+    $USE_MVND = $true
+    $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
+    $MVN_CMD = "mvnd.cmd"
+    break
+  }
+  default {
+    $USE_MVND = $false
+    $MVN_CMD = $script -replace '^mvnw','mvn'
+    break
+  }
+}
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
+if ($env:MVNW_REPOURL) {
+  $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
+  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
+}
+$distributionUrlName = $distributionUrl -replace '^.*/',''
+$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
+$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
+if ($env:MAVEN_USER_HOME) {
+  $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
+}
+$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
+$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
+
+if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
+  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+  exit $?
+}
+
+if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
+  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
+}
+
+# prepare tmp dir
+$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
+$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
+$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
+trap {
+  if ($TMP_DOWNLOAD_DIR.Exists) {
+    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+  }
+}
+
+New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
+
+# Download and Install Apache Maven
+Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+Write-Verbose "Downloading from: $distributionUrl"
+Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+$webclient = New-Object System.Net.WebClient
+if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
+  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
+}
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
+if ($distributionSha256Sum) {
+  if ($USE_MVND) {
+    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
+  }
+  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
+  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
+    Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
+  }
+}
+
+# unzip and move
+Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
+Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
+try {
+  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
+} catch {
+  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
+    Write-Error "fail to move MAVEN_HOME"
+  }
+} finally {
+  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+}
+
+Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

+ 179 - 0
pom.xml

@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.5.2</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.example</groupId>
+    <artifactId>place_name_search</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>place_name_search</name>
+    <description>place_name_search</description>
+    <url/>
+    <licenses>
+        <license/>
+    </licenses>
+    <developers>
+        <developer/>
+    </developers>
+    <scm>
+        <connection/>
+        <developerConnection/>
+        <tag/>
+        <url/>
+    </scm>
+    <properties>
+        <geotools.version>25.2</geotools.version>
+        <java.version>17</java.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.62</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.13.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.googlecode.json-simple</groupId>
+            <artifactId>json-simple</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+        <!--        xlsx读取-->
+        <dependency>
+            <groupId>org.apache.xmlbeans</groupId>
+            <artifactId>xmlbeans</artifactId>
+            <version>5.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.opencsv</groupId>
+            <artifactId>opencsv</artifactId>
+            <version>5.7.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>5.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>5.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.13</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.gdal/gdal -->
+        <dependency>
+            <groupId>org.gdal</groupId>
+            <artifactId>gdal</artifactId>
+            <version>3.5.0</version>
+            <type>pom</type>
+        </dependency>
+        <dependency>
+            <groupId>org.osgeo</groupId>
+            <artifactId>proj4j</artifactId>
+            <version>0.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.locationtech.jts</groupId>
+            <artifactId>jts-core</artifactId>
+            <version>1.19.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt-geojson</artifactId>
+            <version>${geotools.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt-main</artifactId>
+            <version>${geotools.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt-opengis</artifactId>
+            <version>${geotools.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt-shapefile</artifactId>
+            <version>${geotools.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt-metadata</artifactId>
+            <version>${geotools.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <!-- Spring Data JPA -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <!-- PostgreSQL -->
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.20</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 13 - 0
src/main/java/com/example/poiaddr/PoiAddrApplication.java

@@ -0,0 +1,13 @@
+package com.example.poiaddr;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class PoiAddrApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(PoiAddrApplication.class, args);
+    }
+
+}

+ 266 - 0
src/main/java/com/example/poiaddr/controller/PoiAddressController.java

@@ -0,0 +1,266 @@
+package com.example.poiaddr.controller;
+
+import com.example.poiaddr.entity.PoiAddress;
+import com.example.poiaddr.service.PoiAddressService;
+import com.example.poiaddr.util.ExcelReaderUtils;
+import com.example.poiaddr.util.RequestUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.geom.Point;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("/poiAddress")
+public class PoiAddressController {
+
+    @Value("${zip_file_path}")
+    private String ZIP_FILE_PATH;
+    @Value("${zip_file_name}")
+    private String outFileName;
+
+    @Resource
+    private PoiAddressService poiAddressService;
+
+    //    查询所有数据
+    @GetMapping(value = "/getAll")
+    public List<PoiAddress> getAll() {
+        return poiAddressService.findAll();
+    }
+
+    //    根据uuid更新或添加数据
+    @PostMapping(value = "/update")
+    public String update(@RequestBody PoiAddress poiAddress) {
+        if (poiAddress.getUuid() != null) {
+            poiAddressService.update(poiAddress);
+            return "更新成功";
+        } else {
+            poiAddress.setUuid(UUID.randomUUID().toString());
+            GeometryFactory geometryFactory = new GeometryFactory();
+            Point point = geometryFactory.createPoint(new Coordinate(121.21, 31.31));
+            poiAddress.setLocation(point.toString());
+            poiAddressService.save(poiAddress);
+            return "插入成功";
+        }
+    }
+
+    //    地址查询
+    @GetMapping(value = "/selectAddressInfo/{address}")
+    public Object selectAddressInfo(@PathVariable("address") String address) {
+        return RequestUtils.request(address);
+    }
+
+    //    创建一个方法能读取xlsx文件数据并返回List<Map>集合
+//    创建一个setList集合判断文档中的数据不能地址重复
+//    然后根据这个list集合创建多线程请求数据并插入到数据库中
+//    filePath:C:\Users\Liumouren\Desktop\临时文件\元以科技\青浦\青浦城建所\poiAddr\doc\
+    @GetMapping(value = "/test")
+    public Object test() {
+//        try {
+////          根据文件路径得到下面的所有文件集合
+//            List<File> fileList = ExcelReaderUtils.listFilesInDirectory("C:\\Users\\Liumouren\\Desktop\\临时文件\\元以科技\\青浦\\青浦城建所\\poiAddr\\doc\\");
+////          根据文件集合得到
+//            List<Map<String, String>> errorData = new ArrayList<>();
+//            Set<String> addressSet = new HashSet<>();
+//            for (File fileItem : fileList) {
+//                if (fileItem.getPath().contains(".xlsx") && fileItem.getPath().contains("marge_excel_uuid")) {
+//                    List<Map<String, Object>> dataList = ExcelReaderUtils.readExcel(fileItem.getPath());
+//                    for (Map<String, Object> map : dataList) {
+//                        if (map.containsKey("详细地址")) {
+//                            addressSet.add(map.get("详细地址").toString());
+//                        }
+//                    }
+//                }
+//            }
+//
+////            得到geojson中的所有的地址名称
+////            Set<String> addressSet = JacksonExample.getAddressList();
+////          测试请求结果
+//            ArrayList<JSONObject> resultList = new ArrayList<>();
+//            ArrayList<String> addressList = new ArrayList<>();
+//            for (String addrStr : addressSet) {
+//                String addrStr2 = StringUtils.deleteWhitespace(addrStr);
+//                if (addrStr2.length() > 5) {
+//                    addressList.add(addrStr2);
+//                } else {
+//                    Map<String, String> error = new HashMap<>();
+//                    error.put("错误地址:", addrStr2);
+//                    error.put("msg", "地址长度不规范");
+//                    errorData.add(error);
+//                }
+//            }
+//            int threadCount = 10; // 设置线程数量
+//            ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
+//            // 将集合拆分成多个子任务
+//            int partSize = addressList.size() / threadCount;
+//            for (int i = 0; i < threadCount; i++) {
+//                int startIndex = i * partSize;
+//                int endIndex = (i == threadCount - 1) ? addressList.size() : (i + 1) * partSize;
+//                List<String> subList = addressList.subList(startIndex, endIndex);
+//                // 提交Runnable任务到线程池
+//                Runnable runnable = () -> {
+//                    for (String addrStr2 : subList) {
+//                        String resultStr = RequestUtils.request(addrStr2);
+//                        if (resultStr != null && resultStr.contains("result")) {
+//                            JSONParser jsonParser = new JSONParser();
+//                            try {
+//                                JSONObject resultObject = (JSONObject) jsonParser.parse(resultStr);
+//                                JSONArray result = (JSONArray) resultObject.get("result");
+//                                if (result.size() > 0) {
+//                                    System.out.println(addrStr2 + "------解析成功数据:" + jsonParser.parse(resultStr));
+//                                    resultList.add(resultObject);
+//                                } else {
+//                                    System.err.println(addrStr2 + "------解析失败数据:" + resultStr);
+//                                    Map<String, String> error = new HashMap<>();
+//                                    error.put("错误地址:", addrStr2);
+//                                    error.put("msg", "地名地址解析失败");
+//                                    errorData.add(error);
+//                                }
+//                            } catch (Exception e) {
+//                                System.err.println(addrStr2 + "------解析失败数据:" + resultStr);
+//                                Map<String, String> error = new HashMap<>();
+//                                error.put("错误地址:", addrStr2);
+//                                error.put("msg", "地名地址解析失败");
+//                                errorData.add(error);
+//                            }
+//                        }
+//                    }
+//                };
+//                executorService.submit(runnable);
+//            }
+//
+//            // 关闭线程池(不再接受新任务,但会等待已提交任务完成)
+//            executorService.shutdown();
+//            // 等待所有任务完成
+//            try {
+//                while (!executorService.isTerminated()) {
+//                    Thread.sleep(100);
+//                }
+//                System.out.println("所有任务已完成");
+//                for (JSONObject resultItem : resultList) {
+//                    JSONArray result = (JSONArray) resultItem.get("result");
+//                    JSONObject resultData = (JSONObject) result.get(0);
+//                    JSONObject extData = (JSONObject) resultData.get("ext_data");
+//                    PoiAddress poiAddress = new PoiAddress();
+//                    poiAddress.setUuid(UUID.randomUUID().toString());
+//                    poiAddress.setAddress(extData.get("address").toString());
+//                    poiAddress.setAddressCode(extData.get("address_code").toString());
+//                    poiAddress.setLocation(resultData.get("location").toString());
+//                    poiAddress.setBuilding(extData.get("building").toString());
+//                    poiAddress.setAttachInfo(extData.get("attach_info").toString());
+//                    poiAddress.setBuildingAlias(extData.get("building_alias").toString());
+//                    poiAddress.setCoordAdcode(extData.get("coord_adcode").toString());
+//                    poiAddress.setDataOperation(extData.get("data_operation").toString());
+//                    poiAddress.setDataSource(extData.get("data_source").toString());
+//                    poiAddress.setDataOperationCheck(extData.get("data_operation_check").toString());
+//                    poiAddress.setFloor(extData.get("floor").toString());
+//                    poiAddress.setHistoryData(extData.get("history_data").toString());
+//                    poiAddress.setManualMark(extData.get("manual_mark").toString());
+//                    poiAddress.setName1(extData.get("name1").toString());
+//                    poiAddress.setNo1(extData.get("no1").toString());
+//                    poiAddress.setNo2(extData.get("no2").toString());
+//                    poiAddress.setNo3(extData.get("no3").toString());
+//                    poiAddress.setNo4(extData.get("no4").toString());
+//                    poiAddress.setOperationRemark(extData.get("operation_remark").toString());
+//                    poiAddress.setOperationRemarkCheck(extData.get("operation_remark_check").toString());
+//                    poiAddress.setParentAddressCode(extData.get("parent_address_code").toString());
+//                    poiAddress.setPointB(extData.get("point_b").toString());
+//                    poiAddress.setPointL(extData.get("point_l").toString());
+//                    poiAddress.setPointX(extData.get("point_x").toString());
+//                    poiAddress.setPointY(extData.get("point_y").toString());
+//                    poiAddress.setPoiString(extData.get("poi_string").toString());
+//                    poiAddress.setRegionJd(extData.get("region_jd").toString());
+//                    poiAddress.setRegionJw(extData.get("region_jw").toString());
+//                    poiAddress.setRegionQx(extData.get("region_jw").toString());
+//                    poiAddress.setRegionSs(extData.get("region_ss").toString());
+//                    poiAddress.setRegionXq(extData.get("region_xq").toString());
+//                    poiAddress.setRegionXqAlias(extData.get("region_xq_alias").toString());
+//                    poiAddress.setRelationExtraAlias(extData.get("relation_extra_alias").toString());
+//                    poiAddress.setRelationSnMark(extData.get("relation_sn_mark").toString());
+//                    poiAddress.setRoomNo(extData.get("room_no").toString());
+//                    poiAddress.setRoomNoAlias(extData.get("room_no_alias").toString());
+//                    poiAddress.setSemanticsSource(extData.get("semantics_source").toString());
+//                    poiAddress.setSourceAddress(extData.get("source_address").toString());
+//                    poiAddress.setSpecificationUpdateMark(extData.get("specification_update_mark").toString());
+//                    poiAddress.setSubRegionXq(extData.get("sub_region_xq").toString());
+//                    poiAddress.setUnit(extData.get("unit").toString());
+//                    poiAddress.setUnitAlias(extData.get("unit_alias").toString());
+//                    poiAddressService.save(poiAddress);
+//                }
+////              将异常的数据保存为一个json文件
+//                if (errorData.size() > 0) {
+//                    ObjectMapper objectMapper = new ObjectMapper();
+//                    String outputFilePath = "C:\\Users\\Liumouren\\Desktop\\errorAddressData.json"; // 输出文件路径,可按需修改
+//                    FileOutputStream fos = new FileOutputStream(new File(outputFilePath));
+//                    objectMapper.writeValue(fos, errorData);
+//                    fos.close();
+//                }
+//                System.out.println("解析文件得到的地址个数:" + addressSet.size() + ",异常的有" + errorData.size());
+//                return "解析文件得到的地址个数:" + addressSet.size() + ",异常的有" + errorData.size();
+//            } catch (InterruptedException e) {
+//                e.printStackTrace();
+//                return e;
+//            }
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//            return e;
+//        }
+        return "test";
+    }
+
+
+    /**
+     * 地名查询任务接口
+     * * 参数:
+     * ** 必填:
+     * *** file: xlsx、csv、geojson、shape
+     * *** addrColNames: 地名地址字段名称数组,依次查询
+     * ** 非必填:
+     * *** inCoordinate: 输入坐标系
+     * *** latLonColName: 经纬度字段名称,如果长度为一,经纬度字段分隔符为必填
+     * *** latLonSplitStr: 经纬度字段分隔符
+     * *** matchingDistance: 匹配距离,如果不为空,经纬度字段名称不能为空
+     * *** outCoordinate: 输出坐标系(默认为wgs84)
+     * *** matchingLevel: 匹配等级,详情见xmind文件
+     * *** regionalJudgment: 区域判断,geojson、shape文件[前端可以内置一些常用的区域文件,通过下拉框的方式进行选择]
+     * *** outFileType: 输出文件类型【xlsx、csv、geojson、shape】
+     *
+     * @return Object
+     */
+    @PostMapping(value = "/nameQueryTaskInterface", produces = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public Object GeoCoordinate(HttpServletResponse response, @RequestParam(name = "file") MultipartFile file,
+                                @RequestParam(name = "addrColNames") String addrColNames,
+                                @RequestParam(name = "inCoordinate", required = false) String inCoordinate,
+                                @RequestParam(name = "latLonColName", required = false) String latLonColName,
+                                @RequestParam(name = "latLonSplitStr", required = false) String latLonSplitStr,
+                                @RequestParam(name = "matchingDistance", required = false) String matchingDistance,
+                                @RequestParam(name = "outCoordinate", required = false) String outCoordinate,
+                                @RequestParam(name = "matchingLevel", required = false) String matchingLevel,
+                                @RequestParam(name = "regionalJudgment", required = false) MultipartFile regionalJudgment,
+                                @RequestParam(name = "outFileType", required = false) String outFileType) throws IOException {
+        if ((file != null && !file.isEmpty()) || (addrColNames != null && !addrColNames.isEmpty())) {
+            return null;
+        } else {
+            return "file或addrColName不能为空!";
+        }
+    }
+
+}

+ 11 - 0
src/main/java/com/example/poiaddr/dao/PoiAddressRepository.java

@@ -0,0 +1,11 @@
+package com.example.poiaddr.dao;
+
+import com.example.poiaddr.entity.PoiAddress;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Service;
+
+@Service
+public interface PoiAddressRepository extends JpaRepository<PoiAddress, String> {
+
+//    Integer getByAddressLike(String address);
+}

+ 163 - 0
src/main/java/com/example/poiaddr/entity/PoiAddress.java

@@ -0,0 +1,163 @@
+package com.example.poiaddr.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.persistence.Id;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @Description  
+ * @Author  LiuMengxiang
+ * @Date 2024-11-18 15:48:33 
+ */
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@Entity
+@Table ( name ="poi_address" , schema = "")
+public class PoiAddress  implements Serializable {
+
+	private static final long serialVersionUID =  6661768566542572780L;
+
+   	@Column(name = "location" )
+	private String location;
+
+   	@Column(name = "poi_string" )
+	private String poiString;
+
+   	@Column(name = "relation_sn_mark" )
+	private String relationSnMark;
+
+   	@Column(name = "region_xq" )
+	private String regionXq;
+
+   	@Column(name = "region_jd" )
+	private String regionJd;
+
+   	@Column(name = "building" )
+	private String building;
+
+   	@Column(name = "region_xq_alias" )
+	private String regionXqAlias;
+
+   	@Column(name = "no1" )
+	private String no1;
+
+   	@Column(name = "no2" )
+	private String no2;
+
+   	@Column(name = "no3" )
+	private String no3;
+
+   	@Column(name = "no4" )
+	private String no4;
+
+   	@Column(name = "update_time" )
+	private Date updateTime;
+
+   	@Column(name = "coord_adcode" )
+	private String coordAdcode;
+
+   	@Column(name = "specification_update_mark" )
+	private String specificationUpdateMark;
+
+   	@Column(name = "point_y" )
+	private String pointY;
+
+   	@Column(name = "region_jw" )
+	private String regionJw;
+
+   	@Column(name = "point_x" )
+	private String pointX;
+
+   	@Column(name = "source_address" )
+	private String sourceAddress;
+
+   	@Column(name = "operation_remark" )
+	private String operationRemark;
+
+   	@Column(name = "attach_info" )
+	private String attachInfo;
+
+   	@Column(name = "room_no_alias" )
+	private String roomNoAlias;
+
+   	@Column(name = "data_operation" )
+	private String dataOperation;
+
+   	@Column(name = "unit_alias" )
+	private String unitAlias;
+
+   	@Column(name = "room_no" )
+	private String roomNo;
+
+   	@Column(name = "floor" )
+	private String floor;
+
+   	@Column(name = "manual_mark" )
+	private String manualMark;
+
+   	@Column(name = "address_code" )
+	private String addressCode;
+
+   	@Column(name = "relation_extra_alias" )
+	private String relationExtraAlias;
+
+   	@Column(name = "point_l" )
+	private String pointL;
+
+   	@Column(name = "address" )
+	private String address;
+
+   	@Column(name = "create_time" )
+	private Date createTime;
+
+   	@Column(name = "region_ss" )
+	private String regionSs;
+
+   	@Column(name = "building_alias" )
+	private String buildingAlias;
+
+   	@Column(name = "point_b" )
+	private String pointB;
+
+   	@Column(name = "operation_remark_check" )
+	private String operationRemarkCheck;
+
+   	@Column(name = "sub_region_xq" )
+	private String subRegionXq;
+
+   	@Column(name = "data_source" )
+	private String dataSource;
+
+   	@Column(name = "parent_address_code" )
+	private String parentAddressCode;
+
+   	@Column(name = "history_data" )
+	private String historyData;
+
+   	@Column(name = "unit" )
+	private String unit;
+
+   	@Column(name = "semantics_source" )
+	private String semanticsSource;
+
+   	@Column(name = "data_operation_check" )
+	private String dataOperationCheck;
+
+   	@Column(name = "region_qx" )
+	private String regionQx;
+
+   	@Column(name = "name1" )
+	private String name1;
+
+	@Id
+   	@Column(name = "uuid" )
+	private String uuid;
+}

+ 12 - 0
src/main/java/com/example/poiaddr/service/PoiAddressService.java

@@ -0,0 +1,12 @@
+package com.example.poiaddr.service;
+
+import com.example.poiaddr.entity.PoiAddress;
+
+import java.util.List;
+
+public interface PoiAddressService {
+    PoiAddress save(PoiAddress poiAddress);
+//    自定义查询:根据地址关键字模糊查询
+    List<PoiAddress> findAll();
+    PoiAddress update(PoiAddress poiAddress);
+}

+ 49 - 0
src/main/java/com/example/poiaddr/service/impl/PoiAddressServiceImpl.java

@@ -0,0 +1,49 @@
+package com.example.poiaddr.service.impl;
+
+import com.example.poiaddr.dao.PoiAddressRepository;
+import com.example.poiaddr.entity.PoiAddress;
+import com.example.poiaddr.service.PoiAddressService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import javax.persistence.EntityManager;
+import java.util.List;
+
+@Service
+public class PoiAddressServiceImpl implements PoiAddressService {
+
+    @Resource
+    private PoiAddressRepository poiAddressRepository;
+
+    @Autowired
+    private EntityManager entityManager;
+
+    @Override
+    public PoiAddress save(PoiAddress poiAddress) {
+        return poiAddressRepository.save(poiAddress);
+    }
+
+    @Override
+    public List<PoiAddress> findAll() {
+        List<PoiAddress> poiAddressList = poiAddressRepository.findAll();
+        return poiAddressList;
+    }
+
+    /**
+     * 根据uuid查询数据并更新新的数据到数据库
+     *
+     * @param poiAddress
+     * @return
+     */
+    @Transactional
+    public PoiAddress update(PoiAddress poiAddress) {
+        PoiAddress poiAddress1 = entityManager.find(PoiAddress.class, poiAddress.getUuid());
+        if (poiAddress1 != null) {
+            return entityManager.merge(poiAddress);
+        } else {
+            return null;
+        }
+    }
+}

+ 742 - 0
src/main/java/com/example/poiaddr/util/CoordTransform.java

@@ -0,0 +1,742 @@
+package com.example.poiaddr.util;
+
+import org.opengis.referencing.operation.Projection;
+import org.osgeo.proj4j.*;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CoordTransform {
+
+    private final double x_PI = (Math.PI * 3000.0) / 180.0;
+    private final double ee = 0.00669342162296594323;
+    private final double a = 6378245.0;
+
+
+    private final double BD_FACTOR = (3.14159265358979324 * 3000.0) / 180.0;
+    private final double PI = Math.PI;
+    private final double RADIUS = 6378245.0;
+    private final double EE = 0.00669342162296594323;
+
+
+    // 定义常量
+    private final double A = 6378245.0;
+
+    public enum Projs {
+        WGS84, GCJ02, BD09, UTM4, SHCJ, METER, DEGREE
+    }
+
+    public enum EPSG {
+        WGS84("+proj=longlat +datum=WGS84 +no_defs"),
+        MERCATOR("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs"),
+        GAUSS_KRUGER("+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs");
+
+        private final String projString;
+
+        EPSG(String projString) {
+            this.projString = projString;
+        }
+
+        public String getProjString() {
+            return projString;
+        }
+    }
+
+    public static boolean outOfSh(double lng, double lat){
+        lat += lat;
+        lng +=lng;
+        return !(lng > 115.487 && lng < 123.696 && lat > 28.260 && lat < 33.521);
+    }
+
+    private static CoordTransform instance = new CoordTransform();
+    CoordTransform(){}
+    public static CoordTransform getInstance(){
+        if(instance == null) {
+            instance = new CoordTransform();
+        }
+        return instance;
+    }
+
+
+    // 定义投影字典
+    private static final List<Projection> projs = new ArrayList<>();
+
+    // 定义坐标转换方法
+    public double[] wgs84ToShcj(double x, double y) {
+        if (outOfChina(x, y)) {
+            return new double[]{x, y};
+        } else {
+            double[] dlatLng = transformLatLng(x - 105.0, y - 35.0);
+            double radLat = (y / 180.0) * PI;
+            double magic = Math.sin(radLat);
+            magic = 1 - ee * magic * magic;
+            double sqrtMagic = Math.sqrt(magic);
+            dlatLng[0] = (dlatLng[0] * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * PI);
+            dlatLng[1] = (dlatLng[1] * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * PI);
+            double mglat = y + dlatLng[0];
+            double mglng = x + dlatLng[1];
+            return new double[]{mglng, mglat};
+        }
+    }
+
+    // 定义坐标转换方法
+    public double[] gcj02ToWgs84(double x, double y) {
+        if (outOfChina(x, y)) {
+            return new double[]{x, y};
+        } else {
+            double[] dlatLng = transformLatLng(x - 105.0, y - 35.0);
+            double radLat = (y / 180.0) * PI;
+            double magic = Math.sin(radLat);
+            magic = 1 - ee * magic * magic;
+            double sqrtMagic = Math.sqrt(magic);
+            dlatLng[0] = (dlatLng[0] * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * PI);
+            dlatLng[1] = (dlatLng[1] * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * PI);
+            double mglat = y + dlatLng[0];
+            double mglng = x + dlatLng[1];
+            return new double[]{x * 2 - mglng, y * 2 - mglat};
+        }
+    }
+
+    // 定义判断是否在中国境内的方法
+    public boolean outOfChina(double x, double y) {
+        // 纬度 3.86~53.55,经度 73.66~135.05
+        return!(x > 73.66 && x < 135.05 && y > 3.86 && y < 53.55);
+    }
+
+    // 定义坐标转换方法
+    public double[] transformLatLng(double x, double y) {
+        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
+        ret += ((20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0) / 3.0;
+        ret += ((20.0 * Math.sin(y * PI) + 40.0 * Math.sin((y / 3.0) * PI)) * 2.0) / 3.0;
+        ret += ((160.0 * Math.sin((y / 12.0) * PI) + 320 * Math.sin((y * PI) / 30.0)) * 2.0) / 3.0;
+        return new double[]{ret, ret};
+    }
+
+    // 定义经纬度转米的方法
+    public double[] degreeToMeter(double x, double y) {
+        double lon = (x * 20037508.34) / 180;
+        double lat = Math.log(Math.tan(((90 + y) * PI) / 360)) / (PI / 180);
+        lat = (lat * 20037508.34) / 180;
+        return new double[]{lon, lat};
+    }
+
+    // 定义米转经纬度的方法
+    public double[] meterToDegree(double x, double y) {
+        double lon = (x / 20037508.34) * 180;
+        double lat = (y / 20037508.34) * 180;
+        lat = (180 / PI) * (2 * Math.atan(Math.exp((lat * PI) / 180)) - PI / 2);
+        return new double[]{lon, lat};
+    }
+
+    // 定义 WGS84 坐标转上海城建的方法
+    public double[] wgs84ToShcj2(double x, double y) {
+        double[] xy = shcjGetUTMFromWGS(x, y);
+        return utmToShcj4(xy[0], xy[1]);
+    }
+
+    // 定义 UTM 转上海城建的方法
+    public double[] utmToShcj4(double x, double y) {
+        double DX = -500199.29965;
+        double DY = -3457078.805985;
+        double T = 0.0000001755;
+        double K = 1.0004000106;
+        return covertByFourParm(x, y, DX, DY, T, K);
+    }
+
+    // 定义上海城建坐标转 UTM 的方法
+    public double[] shcjGetUTMFromWGS(double lon, double lat) {
+        double a = 6378137;
+        double b = 6356752.3142451;
+        double f = (a - b) / a;
+
+        double eSquare = 2 * f - f * f;
+        double k0 = 0.9996;
+        double lonOrigin = 121.46714714;
+        double FN = 0;
+        // # 确保 longtitude 位于-180.00----179.9 之间
+        double lonTemp = lon + 180 - Math.floor((lon + 180) / 360) * 360 - 180;
+        double latRad = (lat * PI) / 180;
+        double lonRad = (lonTemp * PI) / 180;
+        double lonOriginRad = (lonOrigin * PI) / 180;
+        double e2Square = eSquare / (1 - eSquare);
+
+        double V = a / Math.sqrt(1 - eSquare * Math.pow(Math.sin(latRad), 2));
+        double T = Math.pow(Math.tan(latRad), 2);
+        double C = e2Square * Math.pow(Math.cos(latRad), 2);
+        double A = Math.cos(latRad) * (lonRad - lonOriginRad);
+        double M = a * ((1 - eSquare / 4 - (3 * Math.pow(eSquare, 2)) / 64 - (5 * Math.pow(eSquare, 3)) / 256) * latRad - ((3 * eSquare) / 8 + (3 * Math.pow(eSquare, 2)) / 32 + (45 * Math.pow(eSquare, 3)) / 1024) * Math.sin(2 * latRad) + ((15 * Math.pow(eSquare, 2)) / 256 + (45 * Math.pow(eSquare, 3)) / 1024) * Math.sin(4 * latRad) - ((35 * Math.pow(eSquare, 3)) / 3072) * Math.sin(6 * latRad));
+
+        // # x
+        double UTMEasting = k0 * V * (A + ((1 - T + C) * Math.pow(A, 3)) / 6 + ((5 - 18 * T + Math.pow(T, 2) + 72 * C - 58 * e2Square) * Math.pow(A, 5)) / 120) + 500000.0;
+        //  # y
+        double UTMNorthing = k0 * (M + V * Math.tan(latRad) * (Math.pow(A, 2) / 2 + ((5 - T + 9 * C + 4 * Math.pow(C, 2)) * Math.pow(A, 4)) / 24 + ((61 - 58 * T + Math.pow(T, 2) + 600 * C - 330 * e2Square) * Math.pow(A, 6)) / 720));
+        //# 南半球纬度起点为 10000000.0m
+        UTMNorthing += FN;
+        double[] xy = new double[2];
+        xy[0] = UTMEasting;
+        xy[1] = UTMNorthing;
+        return xy;
+    }
+
+    // 定义上海城建坐标转 WGS84 的方法
+    public double[] shcjToWgs84(double x, double y) {
+        double[] xy = shcjToUtm4(x, y);
+        return shcjGetWGSFromUTM(xy[0], xy[1]);
+    }
+
+    // 定义上海城建坐标转 UTM 的方法
+    public double[] shcjToUtm4(double x, double y) {
+        double DX = 499999.90104;
+        double DY = 3455696.403019;
+        double T = -0.0000001755;
+        double K = 0.999600149344;
+        return covertByFourParm(x, y, DX, DY, T, K);
+    }
+
+    // 定义四参数公式
+    public double[] covertByFourParm(double x, double y, double dx, double dy, double a, double k) {
+        double px = 0;
+        double py = 0;
+        px = x * k * Math.cos(a) - y * k * Math.sin(a) + dx;
+        py = x * k * Math.sin(a) + y * k * Math.cos(a) + dy;
+        double[] xy = new double[2];
+        xy[0] = px;
+        xy[1] = py;
+        return xy;
+    }
+
+    // 定义上海城建坐标转 WGS84 的方法
+    public double[] shcjGetWGSFromUTM(double x, double y) {
+        // WGS84
+        double a = 6378137; // 椭球体长半轴
+        double b = 6356752.3142451; // 椭球体短半轴
+        x = 500000 - x;
+        double k0 = 0.9996;
+        double e = Math.sqrt(1 - Math.pow(b, 2) / Math.pow(a, 2));
+        // # calculate the meridional arc
+        double M = y / k0;
+        //# calculate footprint latitude
+        double mu = M / (a * (1 - Math.pow(e, 2) / 4 - (3 * Math.pow(e, 4)) / 64 - (5 * Math.pow(e, 6)) / 256));
+        double e1 = (1 - Math.pow(1 - Math.pow(e, 2), 1.0 / 2)) / (1 + Math.pow(1 - Math.pow(e, 2), 1.0 / 2));
+        double J1 = (3 * e1) / 2 - (27 * Math.pow(e1, 3)) / 32;
+        double J2 = (21 * Math.pow(e1, 2)) / 16 - (55 * Math.pow(e1, 4)) / 32;
+        double J3 = (151 * Math.pow(e1, 3)) / 96;
+        double J4 = (1097 * Math.pow(e1, 4)) / 512;
+        double fp = mu + J1 * Math.sin(2 * mu) + J2 * Math.sin(4 * mu) + J3 * Math.sin(6 * mu) + J4 * Math.sin(8 * mu);
+        // # Calculate Latitude and Longitude
+        double e2 = Math.pow(e, 2) / (1 - Math.pow(e, 2));
+        double C1 = e2 * Math.pow(Math.cos(fp), 2);
+        double T1 = Math.pow(Math.tan(fp), 2);
+        double R1 = (a * (1 - Math.pow(e, 2))) / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 3.0 / 2);
+        //# This is the same as rho in the forward conversion formulas above, but calculated for fp instead of lat.
+        double N1 = a / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 1.0 / 2);
+        //# This is the same as nu in the forward conversion formulas above, but calculated for fp instead of lat.
+        double D = x / (N1 * k0);
+        double Q1 = (N1 * Math.tan(fp)) / R1;
+        double Q2 = Math.pow(D, 2) / 2;
+        double Q3 = ((5 + 3 * T1 + 10 * C1 - 4 * Math.pow(C1, 2) - 9 * e2) * Math.pow(D, 4)) / 24;
+        double Q4 = ((61 + 90 * T1 + 298 * C1 + 45 * Math.pow(T1, 2) - 3 * Math.pow(C1, 2) - 252 * e2) * Math.pow(D, 6)) / 720;
+        double lat = ((fp - Q1 * (Q2 - Q3 + Q4)) * 180) / PI;
+        // System.out.println("lat===="+Math.toRadians(fp - Q1*(Q2 - Q3 + Q4)));
+        double Q5 = D;
+        double Q6 = ((1 + 2 * T1 + C1) * Math.pow(D, 3)) / 6;
+        double Q7 = ((5 - 2 * C1 + 28 * T1 - 3 * Math.pow(C1, 2) + 8 * e2 + 24 * Math.pow(T1, 2)) * Math.pow(D, 5)) / 120;
+        double lonMid = 121.46714714;
+        double lon = lonMid - (((Q5 - Q6 + Q7) / Math.cos(fp)) * 180) / PI;
+        double[] xy = new double[2];
+        xy[0] = lon;
+        xy[1] = lat;
+        return xy;
+    }
+
+    /***
+     *  计算两个经纬度之间的距离,返回单位米
+     * @param lat1
+     * @param lon1
+     * @param lat2
+     * @param lon2
+     * @return
+     */
+    public double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
+        // 将经纬度转换为弧度
+        double lat1Rad = Math.toRadians(lat1);
+        double lon1Rad = Math.toRadians(lon1);
+        double lat2Rad = Math.toRadians(lat2);
+        double lon2Rad = Math.toRadians(lon2);
+
+//        // 地球半径(单位:千米)
+//        double earthRadius = 6371.0;
+
+        // Haversine公式计算两点之间的距离
+        double dLat = lat2Rad - lat1Rad;
+        double dLon = lon2Rad - lon1Rad;
+        double a = Math.pow(Math.sin(dLat / 2), 2) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.pow(Math.sin(dLon / 2), 2);
+        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+        double distance = RADIUS * c;
+
+        return distance;
+    }
+
+    public boolean checkLatlon(double lat, double lon){
+        if(lat >85 || lat < -85|| lon >180 || lon < -180){
+            return false;
+        }
+        return true;
+    }
+
+    public double[] bd09_to_gcj02(double bd_lon, double bd_lat) {
+        double x = bd_lon - 0.0065;
+        double y = bd_lat - 0.006;
+        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
+        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
+        double gg_lng = z * Math.cos(theta);
+        double gg_lat = z * Math.sin(theta);
+        return new double[]{gg_lng, gg_lat};
+    }
+
+    public double[] gcj02_to_bd09(double lng, double lat) {
+        double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
+        double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
+        double bd_lng = z * Math.cos(theta) + 0.0065;
+        double bd_lat = z * Math.sin(theta) + 0.006;
+        return new double[]{bd_lng, bd_lat};
+    }
+
+    public double[] wgs84_to_gcj02(double lng, double lat) {
+        if (out_of_china(lng, lat)) {
+            return new double[]{lng, lat};
+        } else {
+            double dlat = transformlat(lng - 105.0, lat - 35.0);
+            double dlng = transformlng(lng - 105.0, lat - 35.0);
+            double radlat = (lat / 180.0) * PI;
+            double magic = Math.sin(radlat);
+            magic = 1 - ee * magic * magic;
+            double sqrtmagic = Math.sqrt(magic);
+            dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
+            dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
+            double mglat = lat + dlat;
+            double mglng = lng + dlng;
+            return new double[]{mglng, mglat};
+        }
+    }
+
+//    public double[] gcj02_to_wgs84(double lng, double lat) {
+//        if (out_of_china(lng, lat)) {
+//            return new double[]{lng, lat};
+//        } else {
+//            double dlat = transformlat(lng - 105.0, lat - 35.0);
+//            double dlng = transformlng(lng - 105.0, lat - 35.0);
+//            double radlat = (lat / 180.0) * PI;
+//            double magic = Math.sin(radlat);
+//            magic = 1 - ee * magic * magic;
+//            double sqrtmagic = Math.sqrt(magic);
+//            dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
+//            dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
+//            double mglat = lat + dlat;
+//            double mglng = lng + dlng;
+//            return new double[]{lng * 2 - mglng, lat * 2 - mglat};
+//        }
+//    }
+
+//    public boolean out_of_china(double lng, double lat) {
+//        return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
+//    }
+
+//    public double transformlat(double lng, double lat) {
+//        double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
+//        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
+//        ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;
+//        ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;
+//        return ret;
+//    }
+//
+//    public double transformlng(double lng, double lat) {
+//        double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
+//        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
+//        ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0;
+//        ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0;
+//        return ret;
+//    }
+
+    public double[] degree_to_meter(double lng, double lat) {
+        double x = (lng * 20037508.34) / 180;
+        double y = Math.log(Math.tan(((90 + lat) * PI) / 360)) / (PI / 180);
+        y = (y * 20037508.34) / 180;
+        return new double[]{x, y};
+    }
+
+    public double[] meter_to_degree(double x, double y) {
+        double lon = (x / 20037508.34) * 180;
+        double lat = (y / 20037508.34) * 180;
+        lat = (180 / PI) * (2 * Math.atan(Math.exp((lat * PI) / 180)) - PI / 2);
+        return new double[]{lon, lat};
+    }
+
+//    public double[] wgs84_to_shcj(double x, double y) {
+//        double[] xy = new double[2];
+//        xy = shcj_get_UTM_from_WGS(x, y);
+//        return utm_to_shcj4(xy[0], xy[1]);
+//    }
+
+    public double[] utm_to_shcj4(double x, double y) {
+        double DX = -500199.29965;
+        double DY = -3457078.805985;
+        double T = 0.0000001755;
+        double K = 1.0004000106;
+        return covert_by_four_parm(x, y, DX, DY, T, K);
+    }
+
+    public double[] shcj_get_UTM_from_WGS(double lon, double lat) {
+        double a = 6378137;
+        double b = 6356752.3142451;
+        double f = (a - b) / a;
+        double eSquare = 2 * f - f * f;
+        double k0 = 0.9996;
+        double lonOrigin = 121.46714714;
+        double FN = 0;
+        double lonTemp = lon + 180 - Math.floor((lon + 180) / 360) * 360 - 180;
+        double latRad = (lat * PI) / 180;
+        double lonRad = (lonTemp * PI) / 180;
+        double lonOriginRad = (lonOrigin * PI) / 180;
+        double e2Square = eSquare / (1 - eSquare);
+        double V = a / Math.sqrt(1 - eSquare * Math.pow(Math.sin(latRad), 2));
+        double T = Math.pow(Math.tan(latRad), 2);
+        double C = e2Square * Math.pow(Math.cos(latRad), 2);
+        double A = Math.cos(latRad) * (lonRad - lonOriginRad);
+        double M = a * ((1 - eSquare / 4 - (3 * Math.pow(eSquare, 2)) / 64 - (5 * Math.pow(eSquare, 3)) / 256) * latRad -
+                ((3 * eSquare) / 8 + (3 * Math.pow(eSquare, 2)) / 32 + (45 * Math.pow(eSquare, 3)) / 1024) *
+                        Math.sin(2 * latRad) +
+                ((15 * Math.pow(eSquare, 2)) / 256 + (45 * Math.pow(eSquare, 3)) / 1024) *
+                        Math.sin(4 * latRad) -
+                ((35 * Math.pow(eSquare, 3)) / 3072) * Math.sin(6 * latRad));
+        double UTMEasting = k0 * V * (A + ((1 - T + C) * Math.pow(A, 3)) / 6 +
+                ((5 - 18 * T + Math.pow(T, 2) + 72 * C - 58 * e2Square) * Math.pow(A, 5)) / 120) + 500000.0;
+        double UTMNorthing = k0 * (M + V * Math.tan(latRad) * (Math.pow(A, 2) / 2 +
+                ((5 - T + 9 * C + 4 * Math.pow(C, 2)) * Math.pow(A, 4)) / 24 +
+                ((61 - 58 * T + Math.pow(T, 2) + 600 * C - 330 * e2Square) * Math.pow(A, 6)) / 720));
+        UTMNorthing += FN;
+        return new double[]{UTMEasting, UTMNorthing};
+    }
+
+    public double[] shcj_to_wgs84(double x, double y) {
+        double[] xy = new double[2];
+        xy = shcj_to_utm4(x, y);
+        return shcj_get_WGS_from_UTM(xy[0], xy[1]);
+    }
+
+    public double[] shcj_to_utm4(double x, double y) {
+        double DX = 499999.90104;
+        double DY = 3455696.403019;
+        double T = -0.0000001755;
+        double K = 0.999600149344;
+        return covert_by_four_parm(x, y, DX, DY, T, K);
+    }
+
+    public double[] covert_by_four_parm(double x, double y, double dx, double dy, double a, double k) {
+        double px = x * k * Math.cos(a) - y * k * Math.sin(a) + dx;
+        double py = x * k * Math.sin(a) + y * k * Math.cos(a) + dy;
+        return new double[]{px, py};
+    }
+
+    public double[] shcj_get_WGS_from_UTM(double x, double y) {
+        double a = 6378137;
+        double b = 6356752.3142451;
+        x = 500000 - x;
+        double k0 = 0.9996;
+        double e = Math.sqrt(1 - Math.pow(b, 2) / Math.pow(a, 2));
+        double M = y / k0;
+        double mu = M / (a * (1 - Math.pow(e, 2) / 4 - (3 * Math.pow(e, 4)) / 64 - (5 * Math.pow(e, 6)) / 256));
+        double e1 = (1 - Math.pow(1 - Math.pow(e, 2), 1.0 / 2)) / (1 + Math.pow(1 - Math.pow(e, 2), 1.0 / 2));
+        double J1 = (3 * e1) / 2 - (27 * Math.pow(e1, 3)) / 32;
+        double J2 = (21 * Math.pow(e1, 2)) / 16 - (55 * Math.pow(e1, 4)) / 32;
+        double J3 = (151 * Math.pow(e1, 3)) / 96;
+        double J4 = (1097 * Math.pow(e1, 4)) / 512;
+        double fp = mu + J1 * Math.sin(2 * mu) + J2 * Math.sin(4 * mu) + J3 * Math.sin(6 * mu) + J4 * Math.sin(8 * mu);
+        double e2 = Math.pow(e, 2) / (1 - Math.pow(e, 2));
+        double C1 = e2 * Math.pow(Math.cos(fp), 2);
+        double T1 = Math.pow(Math.tan(fp), 2);
+        double R1 = (a * (1 - Math.pow(e, 2))) / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 3.0 / 2);
+        double N1 = a / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 1.0 / 2);
+        double D = x / (N1 * k0);
+        double Q1 = (N1 * Math.tan(fp)) / R1;
+        double Q2 = Math.pow(D, 2) / 2;
+        double Q3 = ((5 + 3 * T1 + 10 * C1 - 4 * Math.pow(C1, 2) - 9 * e2) * Math.pow(D, 4)) / 24;
+        double Q4 = ((61 + 90 * T1 + 298 * C1 + 45 * Math.pow(T1, 2) - 3 * Math.pow(C1, 2) - 252 * e2) * Math.pow(D, 6)) / 720;
+        double lat = ((fp - Q1 * (Q2 - Q3 + Q4)) * 180) / PI;
+        double Q5 = D;
+        double Q6 = ((1 + 2 * T1 + C1) * Math.pow(D, 3)) / 6;
+        double Q7 = ((5 - 2 * C1 + 28 * T1 - 3 * Math.pow(C1, 2) + 8 * e2 + 24 * Math.pow(T1, 2)) * Math.pow(D, 5)) / 120;
+        double lonmid = 121.46714714;
+        double lon = lonmid - (((Q5 - Q6 + Q7) / Math.cos(fp)) * 180) / PI;
+        return new double[]{lon, lat};
+    }
+
+    public double[] wgs84_to_bd09(double x, double y) {
+        double[] ll = wgs84_to_gcj02(x, y);
+        ll = gcj02_to_bd09(ll[0], ll[1]);
+        return ll;
+    }
+
+    public double[] bd09_to_wgs84(double x, double y) {
+        double[] ll = bd09_to_gcj02(x, y);
+        ll = gcj02_to_wgs84(ll[0], ll[1]);
+        return ll;
+    }
+
+    public double[] gcj02_to_shcj(double x, double y) {
+        double[] ll = gcj02_to_wgs84(x, y);
+        ll = wgs84_to_shcj(ll[0], ll[1]);
+        return ll;
+    }
+
+    public double[] shcj_to_gcj02(double x, double y) {
+        double[] ll = shcj_to_wgs84(x, y);
+        ll = wgs84_to_gcj02(ll[0], ll[1]);
+        return ll;
+    }
+
+    public double[] convert_proj_from_to(Projs from, Projs to, double[] xy) {
+        if (from == to) {
+            return xy;
+        } else {
+            String fromProj = from.toString().toLowerCase();
+            String toProj = to.toString().toLowerCase();
+            String targetMethod = fromProj + "_to_" + toProj;
+            try {
+                return (double[]) this.getClass().getMethod(targetMethod, double.class, double.class).invoke(this, xy[0], xy[1]);
+            } catch (IllegalAccessException e) {
+                throw new RuntimeException(e);
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(e);
+            } catch (NoSuchMethodException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public double[] WGS84ToSH2000(double lng, double lat) {
+        if (out_of_sh(lng, lat)) {
+            return new double[]{lng, lat};
+        } else {
+            double[] templatlng = wgs84_to_shcj(lng, lat);
+            templatlng = meter_to_degree(templatlng[0], templatlng[1]);
+            return new double[]{templatlng[0], templatlng[1]};
+        }
+    }
+
+    public double[] SH2000ToWGS84(double x, double y) {
+        double[] templatlng = meter_to_degree(x, y);
+        if (out_of_sh2000(templatlng[0], templatlng[1])) {
+            return new double[]{x, y};
+        } else {
+            templatlng = shcj_to_wgs84(x, y);
+            return templatlng;
+        }
+    }
+
+    public double[] SH2000lnglatToWGS84(double lng, double lat) {
+        if (out_of_sh2000(lng, lat)) {
+            return new double[]{lng, lat};
+        } else {
+            double[] templatlng = degree_to_meter(lng, lat);
+            templatlng = shcj_to_wgs84(templatlng[0], templatlng[1]);
+            return templatlng;
+        }
+    }
+
+    private boolean out_of_sh(double lng, double lat) {
+        // 实现out_of_sh方法
+        return false;
+    }
+
+    private boolean out_of_sh2000(double lng, double lat) {
+        // 实现out_of_sh2000方法
+        return false;
+    }
+
+    public double[] wgs84_to_shcj(double x, double y) {
+        double[] xy = new double[2];
+        xy = shcj_get_UTM_from_WGS(x, y);
+        return utm_to_shcj4(xy[0], xy[1]);
+    }
+
+
+    public double[] BD09ToGCJ02(double lng, double lat) {
+        double x = lng - 0.0065;
+        double y = lat - 0.006;
+        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * BD_FACTOR);
+        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * BD_FACTOR);
+        double gg_lng = z * Math.cos(theta);
+        double gg_lat = z * Math.sin(theta);
+        return new double[]{gg_lng, gg_lat};
+    }
+
+    public double[] GCJ02ToBD09(double lng, double lat) {
+        lat = +lat;
+        lng = +lng;
+        double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * BD_FACTOR);
+        double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * BD_FACTOR);
+        double bd_lng = z * Math.cos(theta) + 0.0065;
+        double bd_lat = z * Math.sin(theta) + 0.006;
+        return new double[]{bd_lng, bd_lat};
+    }
+
+    public double[] WGS84ToBD09(double lng, double lat) {
+        double[] GCJ02latlng = WGS84ToGCJ02(lng, lat);
+        double[] BD09latlng = GCJ02ToBD09(GCJ02latlng[0], GCJ02latlng[1]);
+        return BD09latlng;
+    }
+
+    public double[] BD09ToWGS84(double lng, double lat) {
+        double[] GCJ02latlng = BD09ToGCJ02(lng, lat);
+        double[] wgslatlng = GCJ02ToWGS84(GCJ02latlng[0], GCJ02latlng[1]);
+        return wgslatlng;
+    }
+
+    public double[] WGS84ToGCJ02(double lng, double lat) {
+        lat = +lat;
+        lng = +lng;
+        if (out_of_china(lng, lat)) {
+            return new double[]{lng, lat};
+        } else {
+            double[] d = delta(lng, lat);
+            return new double[]{lng + d[0], lat + d[1]};
+        }
+    }
+
+    public double[] GCJ02ToWGS84(double lng, double lat) {
+        lat = +lat;
+        lng = +lng;
+        if (out_of_china(lng, lat)) {
+            return new double[]{lng, lat};
+        } else {
+            double[] d = delta(lng, lat);
+            double mgLng = lng + d[0];
+            double mgLat = lat + d[1];
+            return new double[]{lng * 2 - mgLng, lat * 2 - mgLat};
+        }
+    }
+
+    private double[] delta(double lng, double lat) {
+        double dLng = transformLng(lng - 105, lat - 35);
+        double dLat = transformLat(lng - 105, lat - 35);
+        double radLat = (lat / 180) * PI;
+        double magic = Math.sin(radLat);
+        magic = 1 - EE * magic * magic;
+        double sqrtMagic = Math.sqrt(magic);
+        dLng = (dLng * 180) / ((RADIUS / sqrtMagic) * Math.cos(radLat) * PI);
+        dLat = (dLat * 180) / (((RADIUS * (1 - EE)) / (magic * sqrtMagic)) * PI);
+        return new double[]{dLng, dLat};
+    }
+
+    private double transformLng(double lng, double lat) {
+        lat = +lat;
+        lng = +lng;
+        double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
+        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
+        ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0;
+        ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0;
+        return ret;
+    }
+
+    private double transformLat(double lng, double lat) {
+        lat = +lat;
+        lng = +lng;
+        double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
+        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
+        ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;
+        ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;
+        return ret;
+    }
+
+    private boolean out_of_china(double lng, double lat) {
+        lat = +lat;
+        lng = +lng;
+        return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
+    }
+
+    private CRSFactory crsFactory = new CRSFactory();
+
+    // 定义84坐标系
+    private String wgs84Str = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
+    //    private CoordinateReferenceSystem wgs84 = crsFactory.createFromParameters(
+//            "WGS84", wgs84Str);
+    private CoordinateReferenceSystem wgs84 =
+            crsFactory.createFromName("EPSG:4326");
+
+    // 定义CGCS2000坐标系
+    private String cgcs2000Str = "+proj=utm +zone=50 +ellps=GRS80 +units=m +no_defs";
+    //    private CoordinateReferenceSystem cgcs2000 = crsFactory.createFromParameters(
+//            "CGCS2000", cgcs2000Str);
+    private CoordinateReferenceSystem cgcs2000 =
+            crsFactory.createFromName("EPSG:4490");
+
+    public double[] gcj02_to_wgs84(double lng, double lat) {
+        if (out_of_china(lng, lat)) {
+            return new double[]{lng, lat};
+        } else {
+            double dlat = transformlat(lng - 105.0, lat - 35.0);
+            double dlng = transformlng(lng - 105.0, lat - 35.0);
+            double radlat = (lat / 180.0) * Math.PI;
+            double magic = Math.sin(radlat);
+            magic = 1 - EE * magic * magic;
+            double sqrtmagic = Math.sqrt(magic);
+            dlat = (dlat * 180.0) / (((A * (1 - EE)) / (magic * sqrtmagic)) * Math.PI);
+            dlng = (dlng * 180.0) / ((A / sqrtmagic) * Math.cos(radlat) * Math.PI);
+            double mglat = lat + dlat;
+            double mglng = lng + dlng;
+            return new double[]{lng * 2 - mglng, lat * 2 - mglat};
+        }
+    }
+
+    public double transformlng(double lng, double lat) {
+        double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
+        ret += ((20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0) / 3.0;
+        ret += ((20.0 * Math.sin(lng * Math.PI) + 40.0 * Math.sin((lng / 3.0) * Math.PI)) * 2.0) / 3.0;
+        ret += ((150.0 * Math.sin((lng / 12.0) * Math.PI) + 300.0 * Math.sin((lng / 30.0) * Math.PI)) * 2.0) / 3.0;
+        return ret;
+    }
+
+    public double transformlat(double lng, double lat) {
+        double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
+        ret += ((20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0) / 3.0;
+        ret += ((20.0 * Math.sin(lat * Math.PI) + 40.0 * Math.sin((lat / 3.0) * Math.PI)) * 2.0) / 3.0;
+        ret += ((160.0 * Math.sin((lat / 12.0) * Math.PI) + 320 * Math.sin((lat * Math.PI) / 30.0)) * 2.0) / 3.0;
+        return ret;
+    }
+
+    public double[] wgs84ToCGCS2000(double lng, double lat) {
+
+        // 定义WGS84坐标点
+        ProjCoordinate wgs84Point = new ProjCoordinate(lng, lat);
+
+        // 将WGS84坐标点转换为CGCS2000坐标点
+        ProjCoordinate cgcs2000Point = new ProjCoordinate();
+
+        // 创建坐标转换器
+        CoordinateTransformFactory ctf = new CoordinateTransformFactory();
+        CoordinateTransform transform = ctf.createTransform(wgs84, cgcs2000);
+
+        transform.transform(wgs84Point, cgcs2000Point);
+        System.out.println(cgcs2000Point.x + "," + cgcs2000Point.y);
+        return new double[]{cgcs2000Point.x, cgcs2000Point.y};
+    }
+
+    public double[] cgcs2000ToWGS84(double lng, double lat) {
+        // 定义CGCS2000坐标点
+        ProjCoordinate cgcs2000Point = new ProjCoordinate(lng, lat);
+
+        // 将CGCS2000坐标点转换为WGS84坐标点
+        ProjCoordinate wgs84Point = new ProjCoordinate();
+
+        // 创建坐标转换器
+        CoordinateTransformFactory ctf = new CoordinateTransformFactory();
+        CoordinateTransform transform = ctf.createTransform(cgcs2000, wgs84);
+
+        transform.transform(cgcs2000Point, wgs84Point);
+        System.out.println(wgs84Point.x + "," + wgs84Point.y);
+        return new double[]{wgs84Point.x, wgs84Point.y};
+    }
+
+}

+ 346 - 0
src/main/java/com/example/poiaddr/util/Coordinate.java

@@ -0,0 +1,346 @@
+package com.example.poiaddr.util;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
+import java.math.BigDecimal;
+
+/**
+ * 坐标转换工具
+ */
+public class Coordinate {
+
+    private static Coordinate instance = new Coordinate();
+    public static Coordinate getInstance(){
+        return instance;
+    }
+
+    private static final double x_PI = (Math.PI * 3000.0) / 180.0;
+    private static final double PI = Math.PI;
+    private static final double ee = 0.00669342162296594323;
+    private static final double a = 6378245.0;
+    private static final String[] projs = {
+            "wgs84", // 84坐标
+            "gcj02", // 火星坐标
+            "bd09", // 百度坐标
+            "utm4", // utm坐标
+            "shcj", // 城建坐标
+            "meter", // 米制单位
+            "degree" // 度制单位
+    };
+    private static final String[] epsg = {
+            // WGS 84 - WGS84 - World Geodetic System 1984, used in GPS
+            "4326", "+proj=longlat +datum=WGS84 +no_defs",
+            // WGS 84 / Pseudo-Mercator - Spherical Mercator, Google Maps, OpenStreetMap, Bing, ArcGIS, ESRI
+            "3857", "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs",
+            // CGCS2000 / 3-degree Gauss-Kruger zone 40
+            "4528", "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
+    };
+
+    public static double[] bd09_to_gcj02(double bd_lon, double bd_lat) {
+        double x = bd_lon - 0.0065;
+        double y = bd_lat - 0.006;
+        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
+        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
+        double gg_lng = z * Math.cos(theta);
+        double gg_lat = z * Math.sin(theta);
+        return new double[] {gg_lng, gg_lat};
+    }
+
+    public static double[] gcj02_to_bd09(double lng, double lat) {
+        double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
+        double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
+        double bd_lng = z * Math.cos(theta) + 0.0065;
+        double bd_lat = z * Math.sin(theta) + 0.006;
+        return new double[] {bd_lng, bd_lat};
+    }
+
+    public static double[] wgs84_to_gcj02(double lng, double lat) {
+        if (out_of_china(lng, lat)) {
+            return new double[] {lng, lat};
+        } else {
+            double dlat = transformlat(lng - 105.0, lat - 35.0);
+            double dlng = transformlng(lng - 105.0, lat - 35.0);
+            double radlat = (lat / 180.0) * PI;
+            double magic = Math.sin(radlat);
+            magic = 1 - ee * magic * magic;
+            double sqrtmagic = Math.sqrt(magic);
+            dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
+            dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
+            double mglat = lat + dlat;
+            double mglng = lng + dlng;
+            return new double[] {mglng, mglat};
+        }
+    }
+
+    public static double[] gcj02_to_wgs84(double lng, double lat) {
+        if (out_of_china(lng, lat)) {
+            return new double[] {lng, lat};
+        } else {
+            double dlat = transformlat(lng - 105.0, lat - 35.0);
+            double dlng = transformlng(lng - 105.0, lat - 35.0);
+            double radlat = (lat / 180.0) * PI;
+            double magic = Math.sin(radlat);
+            magic = 1 - ee * magic * magic;
+            double sqrtmagic = Math.sqrt(magic);
+            dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
+            dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
+            double mglat = lat + dlat;
+            double mglng = lng + dlng;
+            return new double[] {lng * 2 - mglng, lat * 2 - mglat};
+        }
+    }
+
+    public static boolean out_of_china(double lng, double lat) {
+        return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
+    }
+
+    public static double transformlat(double lng, double lat) {
+        double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
+        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
+        ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;
+        ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;
+        return ret;
+    }
+
+    public static double transformlng(double lng, double lat) {
+        double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
+        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
+        ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0;
+        ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0;
+        return ret;
+    }
+
+    public static double[] degree_to_meter(double lng, double lat) {
+        double x = (lng * 20037508.34) / 180;
+        double y = Math.log(Math.tan(((90 + lat) * PI) / 360)) / (PI / 180);
+        y = (y * 20037508.34) / 180;
+        return new double[] {x, y};
+    }
+
+    public static double[] meter_to_degree(double x, double y) {
+        double lon = (x / 20037508.34) * 180;
+        double lat = (y / 20037508.34) * 180;
+        lat = (180 / PI) * (2 * Math.atan(Math.exp((lat * PI) / 180)) - PI / 2);
+        return new double[] {lon, lat};
+    }
+
+    public static double[] wgs84_to_shcj(double x, double y) {
+        double[] xy = shcj_get_UTM_from_WGS(x, y);
+        return utm_to_shcj4(xy[0], xy[1]);
+    }
+
+    public static double[] utm_to_shcj4(double x, double y) {
+        double DX = -500199.29965;
+        double DY = -3457078.805985;
+        double T = 0.0000001755;
+        double K = 1.0004000106;
+        return covert_by_four_parm(x, y, DX, DY, T, K);
+    }
+
+    public static double[] shcj_get_UTM_from_WGS(double lon, double lat) {
+        double a = 6378137;
+        double b = 6356752.3142451;
+        double f = (a - b) / a;
+        double eSquare = 2 * f - f * f;
+        double k0 = 0.9996;
+        double lonOrigin = 121.46714714;
+        double FN = 0;
+        double lonTemp = lon + 180 - Math.floor((lon + 180) / 360) * 360 - 180;
+        double latRad = (lat * PI) / 180;
+        double lonRad = (lonTemp * PI) / 180;
+        double lonOriginRad = (lonOrigin * PI) / 180;
+        double e2Square = eSquare / (1 - eSquare);
+        double V = a / Math.sqrt(1 - eSquare * Math.pow(Math.sin(latRad), 2));
+        double T = Math.pow(Math.tan(latRad), 2);
+        double C = e2Square * Math.pow(Math.cos(latRad), 2);
+        double A = Math.cos(latRad) * (lonRad - lonOriginRad);
+        double M = a * ((1 - eSquare / 4 - (3 * Math.pow(eSquare, 2)) / 64 - (5 * Math.pow(eSquare, 3)) / 256) * latRad - ((3 * eSquare) / 8 + (3 * Math.pow(eSquare, 2)) / 32 + (45 * Math.pow(eSquare, 3)) / 1024) * Math.sin(2 * latRad) + ((15 * Math.pow(eSquare, 2)) / 256 + (45 * Math.pow(eSquare, 3)) / 1024) * Math.sin(4 * latRad) - ((35 * Math.pow(eSquare, 3)) / 3072) * Math.sin(6 * latRad));
+        double UTMEasting = k0 * V * (A + ((1 - T + C) * Math.pow(A, 3)) / 6 + ((5 - 18 * T + Math.pow(T, 2) + 72 * C - 58 * e2Square) * Math.pow(A, 5)) / 120) + 500000.0;
+        double UTMNorthing = k0 * (M + V * Math.tan(latRad) * (Math.pow(A, 2) / 2 + ((5 - T + 9 * C + 4 * Math.pow(C, 2)) * Math.pow(A, 4)) / 24 + ((61 - 58 * T + Math.pow(T, 2) + 600 * C - 330 * e2Square) * Math.pow(A, 6)) / 720));
+        UTMNorthing += FN;
+        return new double[] {UTMEasting, UTMNorthing};
+    }
+
+    public static double[] shcj_to_wgs84(double x, double y) {
+        double[] xy = shcj_to_utm4(x, y);
+        return shcj_get_WGS_from_UTM(xy[0], xy[1]);
+    }
+
+    public static double[] shcj_to_utm4(double x, double y) {
+        double DX = 499999.90104;
+        double DY = 3455696.403019;
+        double T = -0.0000001755;
+        double K = 0.999600149344;
+        return covert_by_four_parm(x, y, DX, DY, T, K);
+    }
+
+    public static double[] covert_by_four_parm(double x, double y, double dx, double dy, double a, double k) {
+        double px = x * k * Math.cos(a) - y * k * Math.sin(a) + dx;
+        double py = x * k * Math.sin(a) + y * k * Math.cos(a) + dy;
+        return new double[] {px, py};
+    }
+
+    public static double[] shcj_get_WGS_from_UTM(double x, double y) {
+        double a = 6378137;
+        double b = 6356752.3142451;
+        double f = (a - b) / a;
+        double e2 = 2 * f - f * f;
+        double k0 = 0.9996;
+        double lonOrigin = 121.46714714;
+        double FN = 0;
+        x = x - 500000;
+        double e = Math.sqrt(1 - Math.pow(b, 2) / Math.pow(a, 2));
+        double M = y / k0;
+        double mu = M / (a * (1 - Math.pow(e, 2) / 4 - (3 * Math.pow(e, 4)) / 64 - (5 * Math.pow(e, 6)) / 256));
+        double e1 = (1 - Math.pow(1 - Math.pow(e, 2), 1.0 / 2)) / (1 + Math.pow(1 - Math.pow(e, 2), 1.0 / 2));
+        double J1 = (3 * e1) / 2 - (27 * Math.pow(e1, 3)) / 32;
+        double J2 = (21 * Math.pow(e1, 2)) / 16 - (55 * Math.pow(e1, 4)) / 32;
+        double J3 = (151 * Math.pow(e1, 3)) / 96;
+        double J4 = (1097 * Math.pow(e1, 4)) / 512;
+        double fp = mu + J1 * Math.sin(2 * mu) + J2 * Math.sin(4 * mu) + J3 * Math.sin(6 * mu) + J4 * Math.sin(8 * mu);
+        double e2Square = e2 / (1 - e2);
+        double C1 = e2Square * Math.pow(Math.cos(fp), 2);
+        double T1 = Math.pow(Math.tan(fp), 2);
+        double R1 = (a * (1 - e2)) / Math.pow(1 - e2 * Math.pow(Math.sin(fp), 2), 3.0 / 2);
+        double N1 = a / Math.pow(1 - e2 * Math.pow(Math.sin(fp), 2), 1.0 / 2);
+        double D = x / (N1 * k0);
+        double Q1 = (N1 * Math.tan(fp)) / R1;
+        double Q2 = Math.pow(D, 2) / 2;
+        double Q3 = ((5 + 3 * T1 + 10 * C1 - 4 * Math.pow(C1, 2) - 9 * e2) * Math.pow(D, 4)) / 24;
+        double Q4 = ((61 + 90 * T1 + 298 * C1 + 45 * Math.pow(T1, 2) - 3 * Math.pow(C1, 2) - 252 * e2) * Math.pow(D, 6)) / 720;
+        double lat = ((fp - Q1 * (Q2 - Q3 + Q4)) * 180) / PI;
+        double Q5 = D;
+        double Q6 = ((1 + 2 * T1 + C1) * Math.pow(D, 3)) / 6;
+        double Q7 = ((5 - 2 * C1 + 28 * T1 - 3 * Math.pow(C1, 2) + 8 * e2 + 24 * Math.pow(T1, 2)) * Math.pow(D, 5)) / 120;
+        double lonmid = 121.46714714;
+        double lon = lonmid - (((Q5 - Q6 + Q7) / Math.cos(fp)) * 180) / PI;
+        double[] xy = {lon, lat};
+        return xy;
+    }
+
+    public static double[] wgs84_to_bd09(double x, double y) {
+        double[] ll = wgs84_to_gcj02(x, y);
+        ll = gcj02_to_bd09(ll[0], ll[1]);
+        return ll;
+    }
+
+    public static double[] bd09_to_wgs84(double x, double y) {
+        double[] ll = bd09_to_gcj02(x, y);
+        ll = gcj02_to_wgs84(ll[0], ll[1]);
+        return ll;
+    }
+
+    public static double[] gcj02_to_shcj(double x, double y) {
+        double[] ll = gcj02_to_wgs84(x, y);
+        ll = wgs84_to_shcj(ll[0], ll[1]);
+        return ll;
+    }
+
+    public static double[] shcj_to_gcj02(double x, double y) {
+        double[] ll = shcj_to_wgs84(x, y);
+        ll = wgs84_to_gcj02(ll[0], ll[1]);
+        return ll;
+    }
+
+    public static double[] convert_proj_from_to(String from, String to, double[] xy) {
+        if (from.equals(to)) {
+            return xy;
+        } else {
+            String fromProj = projs[Integer.parseInt(from) - 1];
+            String toProj = projs[Integer.parseInt(to) - 1];
+            String targetMethod = fromProj + "_to_" + toProj;
+            try {
+                return (double[]) Coordinate.class.getMethod(targetMethod, double.class, double.class).invoke(null, xy[0], xy[1]);
+            } catch (Exception e) {
+                e.printStackTrace();
+                return null;
+            }
+        }
+    }
+
+    public static double[] convert_proj_from_to2(String from, String to, double[] xy) {
+        if (from.equals(to)) {
+            return xy;
+        } else {
+            String fromProj = "";
+            String toProj = "";
+            for (int i = 0; i < epsg.length; i += 2) {
+                if (epsg[i].equals(from)) {
+                    fromProj = epsg[i + 1];
+                }
+                if (epsg[i].equals(to)) {
+                    toProj = epsg[i + 1];
+                }
+            }
+            if (!fromProj.isEmpty() && !toProj.isEmpty()) {
+                double[] coor = proj4(fromProj, toProj, xy);
+                return coor;
+            } else {
+                return null;
+            }
+        }
+    }
+
+    public static double[] proj4(String fromProj, String toProj, double[] xy) {
+        // Implement the proj4 conversion here
+        return xy;
+    }
+
+    public JSONArray shcjToWgs84(JSONArray geojson) {
+        for (int i = 0; i < geojson.size(); i++) {
+            JSONObject json = geojson.getJSONObject(i);
+            JSONArray coordinates = json.getJSONObject("geometry").getJSONArray(
+                    "coordinates");
+            resolverCoordinates(coordinates);
+            coordinates.toString();
+        }
+
+        return geojson;
+    }
+
+    public String[] shcjToWgs84(String[] wktStrs){
+        String[] result = new String[wktStrs.length];
+        for(int j = 0; j < wktStrs.length; j ++){
+
+            String[] strs = wktStrs[j].split(" ");
+            String sult = strs[0] + "(((";
+            for(int i = 1; i < strs.length; i += 2){
+                String s1 = strs[i];
+                String s2 = strs[i + 1];
+                s1 = s1.replace("(", "");
+                s1 = s1.replace(")", "");
+                s1 = s1.replace(",", "");
+                s2 = s2.replace("(", "");
+                s2 = s2.replace(")", "");
+                s2 = s2.replace(",", "");
+                double[] tempLatlngsAry =
+                        shcj_to_wgs84(Double.valueOf(s1),
+                                Double.valueOf(s2));
+                sult += tempLatlngsAry[0] + " " + tempLatlngsAry[1] + ", ";
+            }
+            sult = sult.substring(0, sult.length() - 2) + ")))";
+            result[j] = sult;
+        }
+        return result;
+    }
+
+    public void resolverCoordinates(JSONArray coordinates) {
+        if(coordinates.size() > 0){
+            for(int i = 0; i < coordinates.size(); i++){
+                if(coordinates.get(i) instanceof Double || coordinates.get(i) instanceof BigDecimal){
+                    double[] tempLatlngsAry =
+                            shcj_to_wgs84(coordinates.getDouble(0),
+                            coordinates.getDouble(1));
+                    coordinates.clear();
+                    coordinates.add(tempLatlngsAry[0] - 0.19195);
+                    coordinates.add(tempLatlngsAry[1] + 0.00011);
+                    break;
+                } else {
+                    resolverCoordinates(coordinates.getJSONArray(i));
+                }
+            }
+        }
+    }
+
+}

+ 472 - 0
src/main/java/com/example/poiaddr/util/ExcelReaderUtils.java

@@ -0,0 +1,472 @@
+package com.example.poiaddr.util;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.*;
+
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import java.io.FileOutputStream;
+
+/**
+ * xlsx文档解析并输出内容为List<Map<String,String>>
+ * 大文件分割
+ */
+public class ExcelReaderUtils {
+
+    public static void writeToExcel(List<Map<String, Object>> dataList, String filePath) throws IOException {
+        // 创建一个新的工作簿(对应一个Excel文件)
+        Workbook workbook = new XSSFWorkbook();
+        // 创建一个工作表
+        Sheet sheet = workbook.createSheet("Sheet1");
+
+        // 写入表头(从Map的键中获取列名)
+        if (!dataList.isEmpty()) {
+            Map<String, Object> firstMap = dataList.get(0);
+            int colIndex = 0;
+            Row headerRow = sheet.createRow(0);
+            for (String key : firstMap.keySet()) {
+                Cell cell = headerRow.createCell(colIndex++);
+                cell.setCellValue(key);
+            }
+        }
+
+        // 逐行写入数据
+        int rowIndex = 1;
+        for (Map<String, Object> dataMap : dataList) {
+            Row dataRow = sheet.createRow(rowIndex++);
+            int colIndex = 0;
+            for (Object value : dataMap.values()) {
+                Cell cell = dataRow.createCell(colIndex++);
+                if (value instanceof String) {
+                    cell.setCellValue((String) value);
+                } else if (value instanceof Integer) {
+                    cell.setCellValue((Integer) value);
+                } else if (value instanceof Double) {
+                    cell.setCellValue((Double) value);
+                } else if (value instanceof Boolean) {
+                    cell.setCellValue((Boolean) value);
+                } else {
+                    cell.setCellValue(value != null ? value.toString() : "");
+                }
+            }
+        }
+
+        // 将工作簿写入到文件
+        try (FileOutputStream outputStream = new FileOutputStream(filePath)) {
+            workbook.write(outputStream);
+        } finally {
+            workbook.close();
+        }
+    }
+
+    public static List<Map<String, Object>> readExcel(String filePath) throws IOException {
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        FileInputStream fis = new FileInputStream(filePath);
+        IOUtils.setByteArrayMaxOverride(400000000);
+        // 创建工作簿对象,用于代表整个Excel文件
+        Workbook workbook = WorkbookFactory.create(fis);
+        // 这里我们默认读取第一个工作表,如果需要读取指定名称或者索引的工作表可以进行相应修改
+        Sheet sheet = workbook.getSheetAt(0);
+        // 获取表头行
+        Row headerRow = sheet.getRow(0);
+        int headerSize = headerRow.getLastCellNum();
+
+        // 遍历数据行(从第二行开始,第一行是表头)
+        for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
+            Row currentRow = sheet.getRow(rowIndex);
+            Map<String, Object> rowMap = new HashMap<>();
+            for (int cellIndex = 0; cellIndex < headerSize; cellIndex++) {
+                Cell headerCell = headerRow.getCell(cellIndex);
+                Cell currentCell = currentRow.getCell(cellIndex);
+                String headerValue = getCellValue(headerCell).toString();
+                Object currentValue = getCellValue(currentCell);
+                rowMap.put(headerValue, currentValue);
+            }
+            resultList.add(rowMap);
+        }
+
+        workbook.close();
+        fis.close();
+        return resultList;
+    }
+
+
+    public static List<Map<String, Object>> readExcel(File file) throws IOException {
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        FileInputStream fis = new FileInputStream(file);
+        IOUtils.setByteArrayMaxOverride(400000000);
+        // 创建工作簿对象,用于代表整个Excel文件
+        Workbook workbook = WorkbookFactory.create(fis);
+        // 这里我们默认读取第一个工作表,如果需要读取指定名称或者索引的工作表可以进行相应修改
+        Sheet sheet = workbook.getSheetAt(0);
+        // 获取表头行
+        Row headerRow = sheet.getRow(0);
+        int headerSize = headerRow.getLastCellNum();
+
+        // 遍历数据行(从第二行开始,第一行是表头)
+        for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
+            Row currentRow = sheet.getRow(rowIndex);
+            Map<String, Object> rowMap = new HashMap<>();
+            for (int cellIndex = 0; cellIndex < headerSize; cellIndex++) {
+                Cell headerCell = headerRow.getCell(cellIndex);
+                Cell currentCell = currentRow.getCell(cellIndex);
+                String headerValue = getCellValue(headerCell).toString();
+                Object currentValue = getCellValue(currentCell);
+                rowMap.put(headerValue, currentValue);
+            }
+            resultList.add(rowMap);
+        }
+
+        workbook.close();
+        fis.close();
+        return resultList;
+    }
+
+    public static void splitExcelByRows(String inputFilePath, int rowsPerFile) throws IOException {
+        FileInputStream inputStream = new FileInputStream(new File(inputFilePath));
+        IOUtils.setByteArrayMaxOverride(400000000);
+        Workbook workbook = new XSSFWorkbook(inputStream);
+        Sheet sheet = workbook.getSheetAt(0);
+
+        int totalRows = sheet.getLastRowNum() + 1;
+        int fileCount = (totalRows / rowsPerFile) + (totalRows % rowsPerFile == 0? 0 : 1);
+
+        for (int i = 0; i < fileCount; i++) {
+            Workbook newWorkbook = new XSSFWorkbook();
+            Sheet newSheet = newWorkbook.createSheet("Sheet1");
+            int startRow = i * rowsPerFile;
+            int endRow = Math.min((i + 1) * rowsPerFile, totalRows);
+
+            for (int rowIndex = startRow; rowIndex < endRow; rowIndex++) {
+                Row sourceRow = sheet.getRow(rowIndex);
+                Row newRow = newSheet.createRow(rowIndex - startRow);
+                if (sourceRow!= null) {
+                    for (int cellIndex = 0; cellIndex < sourceRow.getLastCellNum(); cellIndex++) {
+                        Cell sourceCell = sourceRow.getCell(cellIndex);
+                        Cell newCell = newRow.createCell(cellIndex);
+                        if (sourceCell!= null) {
+                            switch (sourceCell.getCellType()) {
+                                case STRING:
+                                    newCell.setCellValue(sourceCell.getStringCellValue());
+                                    break;
+                                case NUMERIC:
+                                    newCell.setCellValue(sourceCell.getNumericCellValue());
+                                    break;
+                                case BOOLEAN:
+                                    newCell.setCellValue(sourceCell.getBooleanCellValue());
+                                    break;
+                                // 可以根据实际情况添加更多的类型处理,比如日期等
+                                default:
+                                    newCell.setCellValue("");
+                            }
+                        }
+                    }
+                }
+            }
+
+            String outputFilePath = getOutputFilePath(inputFilePath, i);
+            FileOutputStream outputStream = new FileOutputStream(outputFilePath);
+            newWorkbook.write(outputStream);
+            outputStream.close();
+            newWorkbook.close();
+        }
+
+        workbook.close();
+        inputStream.close();
+    }
+
+    private static String getOutputFilePath(String inputFilePath, int index) {
+        String baseName = inputFilePath.substring(0, inputFilePath.lastIndexOf('.'));
+        String extension = inputFilePath.substring(inputFilePath.lastIndexOf('.'));
+        return baseName + "_part_" + (index + 1) + extension;
+    }
+
+    private static Map<String, String>  updateTableHeader() {
+        Map<String, String> table1colToName = new HashMap<>();
+        table1colToName.put("ID", "序列号");
+        table1colToName.put("TASKID", "任务编号");
+        table1colToName.put("BANLIRESULT_12345", "办理结果");
+        table1colToName.put("APPEAL_EXPLAIN", "诉求认定说明");
+        table1colToName.put("DESCRIPTION_12345", "反馈结论");
+        table1colToName.put("NOT_REASON", "未联原因");
+        table1colToName.put("CASEVALUATION_12345", "是否满意");
+        table1colToName.put("VIEWINFO", "现场查看");
+        table1colToName.put("DISPATCHNOTE", "派遣备注");
+        table1colToName.put("ENDNOTE", "结案备注");
+        table1colToName.put("PARTSN", "部件编号");
+        table1colToName.put("WORKGRID", "工作网格");
+        table1colToName.put("SPEICALSIGN", "案件特殊标识(特征要素)");
+        table1colToName.put("CANCLETIME", "作废时间");
+        table1colToName.put("CONTACTINFO", "联系方式");
+        table1colToName.put("ACCEPTTIME", "接单时间(最后一次主责部门处理完成时间)");
+        table1colToName.put("LASTCONTACTTIME", "首次联系截止时间(最后主责)");
+        table1colToName.put("INFOSOURCENAME", "来源名");
+        table1colToName.put("INFOTYPENAME", "案件属性名");
+        table1colToName.put("INFOBCNAME", "大类名");
+        table1colToName.put("INFOSCNAME", "小类名");
+        table1colToName.put("INFOZCNAME", "子类名");
+        table1colToName.put("STREETNAME", "街道名");
+        table1colToName.put("COMMUNITYNAME", "居委名");
+        table1colToName.put("WORKGRIDCODE", "责任网格");
+        table1colToName.put("EXECUTEDEPTNAME", "最后主责部门");
+        table1colToName.put("REPORTER", "反映人");
+        table1colToName.put("REPORTDEPTNAME", "渠道来源");
+        table1colToName.put("SYNCTIME", "更新时间");
+        table1colToName.put("WP_SOURCE", "工单来源");
+        table1colToName.put("CASESN", "案卷编号");
+        table1colToName.put("INFOSOURCEID", "问题来源");
+        table1colToName.put("DISCOVERTIME", "发现时间");
+        table1colToName.put("PERCREATETIME", "受理时间(最后一次受理时间)");
+        table1colToName.put("CREATETIME", "立案时间(最后一次立案时间)");
+        table1colToName.put("DISPATCHTIME", "派遣时间(最后一次派遣时间)");
+        table1colToName.put("SOLVINGTIME", "处理完成时间(最后一次主责部门处理完成时间)");
+        table1colToName.put("TELASKTIME", "回访时间(最后一次回访时间)");
+        table1colToName.put("ENDTIME", "结案时间");
+        table1colToName.put("STREETCODE", "街道编号");
+        table1colToName.put("COMMUNITYCODE", "村、居村编码");
+        table1colToName.put("GRIDCODE", "万米网格编码");
+        table1colToName.put("COORDX", "X坐标");
+        table1colToName.put("COORDY", "Y坐标");
+        table1colToName.put("ADDRESS", "发生地址");
+        table1colToName.put("INFOTYPEID", "问题类型编码(0,value:部件;1:事件;...)");
+        table1colToName.put("INFOBCCODE", "问题大类编号");
+        table1colToName.put("INFOSCCODE", "问题小类编号");
+        table1colToName.put("INFOZCCODE", "问题子类编码");
+        table1colToName.put("INFOATCODE", "问题管理要点编码");
+        table1colToName.put("DESCRIPTION", "问题描述");
+        table1colToName.put("STATUS", "T_INFO_MAIN表状态");
+        table1colToName.put("DEPTCODE", "立案部门");
+        table1colToName.put("EXECUTEDEPTCODE", "最后一次主责部门");
+        table1colToName.put("INSERTDEPTCODE", "收集部门");
+        table1colToName.put("KEEPERSN", "上报监督员编号");
+        table1colToName.put("INSERTUSER", "记录添加操作员(收集人)");
+        table1colToName.put("URGENTDEGREE", "紧急程度(0:一般;1:紧急)");
+        table1colToName.put("APPROACH", "12345工单处理方式/案卷类型(0:转办; /1:督办; /2:回访复核)");
+        table1colToName.put("SIMILARCASESN", "相关案件编号");
+        table1colToName.put("SERVICETYPE", "业务类型");
+        table1colToName.put("ISANONYMITY", "是否匿名");
+        table1colToName.put("USEREVALUATE", "用户评价/满意度(0,value:满意; /1,value:基本满意; /2,value:不满意)");
+        table1colToName.put("ALLMIDDLETIME", "整体案卷黄灯开始时间(根据紧急程度middle计算的)");
+        table1colToName.put("ALLIMPORTANTTIME", "整体案卷橙灯开始时间(根据紧急程度important计算的)");
+        table1colToName.put("ALLENDTIME", "整体案卷截止时间(红灯开始时间)");
+        table1colToName.put("MIDDLESOLVINGTIME", "处理阶段黄灯开始时间");
+        table1colToName.put("IMPORTANTSOLVINGTIME", "处理阶段橙灯开始时间");
+        table1colToName.put("LASTSOLVINGTIME", "处理阶段红灯开始时间(处理截止时间)");
+        table1colToName.put("CALLBACK_FLAG", "12345回访复核单状态标识(0:否,1:是)");
+        table1colToName.put("URGE_COUNT", "12345催单次数(12345催单时带过来的催单次数)");
+        table1colToName.put("DU_LIMIT", "12345督办时限(天)");
+        table1colToName.put("CASEEND", "是否自行处置");
+        table1colToName.put("BANLIRESULT", "12345办理结果(0,value:解决,1,value:未解决,2,value:部分解决,3,value:不办理退单)");
+        table1colToName.put("ENDRESULT", "结案评价");
+        table1colToName.put("VERIFYRESULT", "最后的核实结果(1,value:属实,0,value:不属实)");
+        table1colToName.put("CHECKRESULT", "最后的核查结果(1,value:完成,0,value:未完成)");
+        table1colToName.put("PRIORITYAREA", "重要区域");
+        table1colToName.put("CONTACTMODE", "反映人联系方式");
+        table1colToName.put("BACKCOUNT", "退单次数(案件所有主责部门累加)");
+        table1colToName.put("HESHICOUNT", "核实次数");
+        table1colToName.put("HECHACOUNT", "核查次数");
+        table1colToName.put("HUIFANGCOUNT", "回访次数");
+        table1colToName.put("HASLEADTYPECOUNT", "领导督办次数");
+        table1colToName.put("HASTENTYPECOUNT", "催办过的次数");
+        table1colToName.put("HOTLINESN", "12319编号,延伸为外系统管理单号");
+        table1colToName.put("JHPT_UPDATE_TIME", "JHPT_UPDATE_TIME");
+        table1colToName.put("JHPT_DELETE", "JHPT_UPDATE_TIME");
+        table1colToName.put("DEPTNAME", "部门名");
+        table1colToName.put("STATUSNAME", "状态名");
+        return table1colToName;
+    }
+    private static String getCellValueAsString(Cell cell) {
+        switch (cell.getCellType()) {
+            case STRING:
+                return cell.getStringCellValue();
+            case NUMERIC:
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    return cell.getDateCellValue().toString();
+                } else {
+                    return String.valueOf(cell.getNumericCellValue());
+                }
+            case BOOLEAN:
+                return String.valueOf(cell.getBooleanCellValue());
+            case FORMULA:
+                try {
+                    return cell.getCellFormula();
+                } catch (Exception e) {
+                    return "";
+                }
+            default:
+                return "";
+        }
+    }
+
+    /**
+     * 替换表头
+     */
+    private static void ModifyExcelHeaderJExcelApi(){
+        try {
+            // 读取现有的Excel文件
+            FileInputStream file = new FileInputStream("C:\\Users\\Liumouren\\Desktop\\临时文件\\元以科技\\青浦\\青浦城建所\\poiAddr\\doc\\tableHeader.xlsx");
+            Workbook workbook = new XSSFWorkbook(file);
+            Map<String, String> table1colToName = updateTableHeader();
+            // 遍历每个工作表
+            for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
+                Sheet sheet = workbook.getSheetAt(sheetIndex);
+                // 获取表头行(假设第一行是表头)
+                Row headerRow = sheet.getRow(0);
+                if (headerRow!= null) {
+                    // 遍历每个表头单元格进行替换
+                    // 遍历表头行中的每个单元格
+                    for (Cell cell : headerRow) {
+                        if (cell!= null) {
+                            String oldHeaderValue = getCellValueAsString(cell);
+                            if (table1colToName.containsKey(oldHeaderValue)) {
+                                cell.setCellValue(table1colToName.get(oldHeaderValue));
+                            }
+                        }
+                    }
+                }
+            }
+            // 保存修改后的Excel文件
+            FileOutputStream outputStream = new FileOutputStream("C:\\Users\\Liumouren\\Desktop\\临时文件\\元以科技\\青浦\\青浦城建所\\poiAddr\\doc\\outPutTableHeader.xlsx");
+            workbook.write(outputStream);
+            outputStream.close();
+            file.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static void XlsxFileSplitByRowRange(String filePath, int tag) {
+        try {
+            // 读取原始xlsx文件
+            Workbook workbook = new XSSFWorkbook(new File(filePath));
+            Sheet sheet = workbook.getSheetAt(0);
+            int totalRows = sheet.getLastRowNum();
+            int rowsPerFile = 10000; // 每个分割文件包含的行数
+            for (int i = 0; i <= totalRows; i += rowsPerFile) {
+                // 创建新的工作簿用于保存分割后的行数据
+                Workbook newWorkbook = new XSSFWorkbook();
+                Sheet newSheet = newWorkbook.createSheet();
+                int endRow = Math.min(i + rowsPerFile, totalRows + 1);
+                for (int j = i; j < endRow; j++) {
+                    Row row = sheet.getRow(j);
+                    if (row != null) {
+                        Row newRow = newSheet.createRow(j - i);
+                        for (Cell cell : row) {
+                            if (cell != null) {
+                                Cell newCell = newRow.createCell(cell.getColumnIndex());
+                                // 复制单元格类型和值
+                                newCell.setCellType(cell.getCellType());
+                                if (cell.getCellType() == CellType.STRING) {
+                                    newCell.setCellValue(cell.getStringCellValue());
+                                } else if (cell.getCellType() == CellType.NUMERIC) {
+                                    newCell.setCellValue(cell.getNumericCellValue());
+                                } else if (cell.getCellType() == CellType.BOOLEAN) {
+                                    newCell.setCellValue(cell.getBooleanCellValue());
+                                }
+                            }
+                        }
+                    }
+                }
+                // 将分割后的行数据保存为新的xlsx文件
+                FileOutputStream outputStream = new FileOutputStream("C:\\Users\\Liumouren\\Desktop\\临时文件\\元以科技\\青浦\\青浦城建所\\poiAddr\\doc\\output_" + tag + "_" + (i / rowsPerFile) + ".xlsx");
+                newWorkbook.write(outputStream);
+                outputStream.close();
+                newWorkbook.close();
+            }
+            workbook.close();
+        } catch (IOException | InvalidFormatException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static Object getCellValue(Cell cell) {
+        if (cell == null) {
+            return null;
+        }
+        CellType cellType = cell.getCellType();
+        switch (cellType) {
+            case STRING:
+                return cell.getStringCellValue();
+            case NUMERIC:
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    return cell.getDateCellValue();
+                } else {
+                    return cell.getNumericCellValue();
+                }
+            case BOOLEAN:
+                return cell.getBooleanCellValue();
+            case FORMULA:
+                return cell.getCellFormula();
+            default:
+                return null;
+        }
+    }
+
+    public static List<File> listFilesInDirectory(String path) {
+        List<File> fileList = new ArrayList<>();
+        File directory = new File(path);
+        // 首先判断给定的路径是否是一个目录
+        if (directory.isDirectory()) {
+            File[] files = directory.listFiles();
+            if (files != null) {
+                for (File file : files) {
+                    if (file.isFile()) {
+                        fileList.add(file);
+                    } else if (file.isDirectory()) {
+                        // 如果是子目录,递归调用获取子目录下的文件
+                        fileList.addAll(listFilesInDirectory(file.getAbsolutePath()));
+                    }
+                }
+            }
+        }
+        return fileList;
+    }
+
+
+    public static void main(String[] args) {
+//        根据Map字段修改表头
+//        ModifyExcelHeaderJExcelApi();
+
+        //          根据文件路径得到下面的所有文件集合
+        List<File> fileList = listFilesInDirectory("C:\\Users\\Liumouren\\Desktop\\临时文件\\元以科技\\青浦\\青浦城建所\\poiAddr\\doc\\");
+//          根据文件集合得到
+//        Set<String> addressSet = new HashSet<>();
+//            TODO 所有文件加入
+        int tagIndex = 0;
+        for (File fileItem : fileList) {
+            if (fileItem.getPath().contains(".xlsx") && fileItem.getPath().contains("marge_excel_uuid")) {
+                System.out.println(fileItem.getPath());
+                tagIndex++;
+//                分割文件
+                XlsxFileSplitByRowRange(fileItem.getPath(), tagIndex);
+            }
+        }
+        System.exit(0);
+/*
+//          测试请求结果
+        ArrayList<String> resultList = new ArrayList<>();
+        ArrayList<String> errorResultList = new ArrayList<>();
+        for (String addrStr : addressSet) {
+            String resultStr = RequestUtils.request(StringUtils.deleteWhitespace(addrStr));
+            if (resultStr != null && resultStr.contains("result")) {
+                JSONParser jsonParser = new JSONParser();
+                try {
+//                        System.out.println(addrStr + "------解析成功数据:" + jsonParser.parse(resultStr));
+                    resultList.add(resultStr);
+                } catch (Exception e) {
+//                        System.err.println(addrStr + "------解析失败数据:" + resultStr);
+                    errorResultList.add(addrStr);
+                }
+            }
+        }
+        System.out.println("总地址个数:" + addressSet.size());
+        System.out.println("解析成功的地址个数:" + resultList.size());
+        System.out.println("解析失败的地址个数:" + errorResultList.size());*/
+    }
+}

+ 88 - 0
src/main/java/com/example/poiaddr/util/RequestUtils.java

@@ -0,0 +1,88 @@
+package com.example.poiaddr.util;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 地址查询请求工具类
+ * 地址:上海市一张图服务
+ */
+public class RequestUtils {
+    public static String request(String address) {
+        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+            String urlF = "https://service-api.onemap.sh.gov.cn/data-service-manage-service/MapProxyApi/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBsaWNhdGlvbl9pZCI6NjEsImFwcGxpY2F0aW9uX25hbWUiOiLpnZLmtabkuozkuInnu7TmnI3liqHns7vnu58iLCJleHAiOjIwNDY2Nzg0MDN9.IKUMdjUX4U1jncIUNren-iotL7duXI90aLECMjpvUX8/address_search/MapServer?query=";
+            String urlE = "&region=310000&page_num=1&page_size=1";
+            HttpGet httpGet = new HttpGet(urlF + address + urlE);
+            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
+                int statusCode = response.getStatusLine().getStatusCode();
+                if (statusCode == 200) {
+                    HttpEntity entity = response.getEntity();
+                    return EntityUtils.toString(entity);
+                } else {
+                    return "请求失败,状态码: " + statusCode;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return e.getMessage();
+        }
+    }
+
+    /**
+     * httpPost 请求,参数类型为formData
+     *
+     * @param url
+     * @param headers
+     * @param formDatas
+     * @return
+     */
+    public static JSONObject requestPost(String url, Map<String, String> headers, Map<String, String> formDatas) {
+        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+            HttpPost httpPost = new HttpPost(url); // 替换为实际的 API 地址
+            if (headers != null && headers.size() > 0) {
+                // 设置自定义 Header
+                for (String key : headers.keySet()) {
+                    httpPost.addHeader(key, headers.get(key));
+                }
+            }
+
+            if (formDatas != null && formDatas.size() > 0) {
+                // 设置 formData
+                List<NameValuePair> formData = new ArrayList<>();
+                for (String key : formDatas.keySet()) {
+                    formData.add(new BasicNameValuePair(key, formDatas.get(key)));
+                }
+                httpPost.setEntity(new UrlEncodedFormEntity(formData));
+            }
+            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+                int statusCode = response.getStatusLine().getStatusCode();
+                if (statusCode == 200) {
+                    HttpEntity entity = response.getEntity();
+                    JSONParser jsonParser = new JSONParser();
+                    return (JSONObject) jsonParser.parse(EntityUtils.toString(entity));
+                } else {
+                    System.err.println("请求失败,状态码: " + statusCode);
+                    return null;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.err.println(e.getMessage());
+            return null;
+        }
+    }
+}

+ 294 - 0
src/main/java/com/example/poiaddr/util/ZipUnit/CompressUtil.java

@@ -0,0 +1,294 @@
+package com.example.poiaddr.util.ZipUnit;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.CRC32;
+import java.util.zip.CheckedOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * @author fhey
+ * @date 2023-05-11 20:48:28
+ * @description: 压缩工具类
+ */
+
+public class CompressUtil {
+
+    private static final Logger logger = LoggerFactory.getLogger(CompressUtil.class);
+
+    /**
+     * 将文件打包到zip并创建文件
+     *
+     * @param sourceFilePath
+     * @param zipFilePath
+     * @throws IOException
+     */
+    public static void createLocalCompressFile(String sourceFilePath, String zipFilePath) throws IOException {
+        createLocalCompressFile(sourceFilePath, zipFilePath, null);
+    }
+
+    /**
+     * 将文件打包到zip并创建文件
+     *
+     * @param sourceFilePath
+     * @param zipFilePath
+     * @param zipName
+     * @throws IOException
+     */
+    public static void createLocalCompressFile(String sourceFilePath, String zipFilePath, String zipName) throws IOException {
+        File sourceFile = new File(sourceFilePath);
+        if (!sourceFile.exists()) {
+            throw new RuntimeException(sourceFilePath + "不存在!");
+        }
+        if(StringUtils.isBlank(zipName)){
+            zipName = sourceFile.getName();
+        }
+        File zipFile = createNewFile(zipFilePath + File.separator + zipName + ".zip");
+        try (FileOutputStream fileOutputStream = new FileOutputStream(zipFile)) {
+            compressFile(sourceFile, fileOutputStream);
+        }
+    }
+
+    /**
+     * 获取压缩文件流
+     *
+     * @param sourceFilePath
+     * @return ByteArrayOutputStream
+     * @throws IOException
+     */
+    public static OutputStream compressFile(String sourceFilePath, OutputStream outputStream) throws IOException {
+        File sourceFile = new File(sourceFilePath);
+        if (!sourceFile.exists()) {
+            throw new RuntimeException(sourceFilePath + "不存在!");
+        }
+        return compressFile(sourceFile, outputStream);
+    }
+
+    /**
+     * 获取压缩文件流
+     *
+     * @param sourceFile
+     * @return ByteArrayOutputStream
+     * @throws IOException
+     */
+    private static OutputStream compressFile(File sourceFile, OutputStream outputStream) throws IOException {
+        try (CheckedOutputStream checkedOutputStream = new CheckedOutputStream(outputStream, new CRC32());
+             ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream)) {
+            doCompressFile(sourceFile, zipOutputStream, StringUtils.EMPTY);
+            return outputStream;
+        }
+    }
+
+    /**
+     * 处理目录下的文件
+     *
+     * @param sourceFile
+     * @param zipOutputStream
+     * @param zipFilePath
+     * @throws IOException
+     */
+    private static void doCompressFile(File sourceFile, ZipOutputStream zipOutputStream, String zipFilePath) throws IOException {
+        // 如果文件是隐藏的,不进行压缩
+        if (sourceFile.isHidden()) {
+            return;
+        }
+        if (sourceFile.isDirectory()) {//如果是文件夹
+            handDirectory(sourceFile, zipOutputStream, zipFilePath);
+        } else {//如果是文件就添加到压缩包中
+            try (FileInputStream fileInputStream = new FileInputStream(sourceFile)) {
+                String fileName = zipFilePath + sourceFile.getName();
+                addCompressFile(fileInputStream, fileName, zipOutputStream);
+            }
+        }
+    }
+
+    /**
+     * 处理文件夹
+     *
+     * @param dir         文件夹
+     * @param zipOut      压缩包输出流
+     * @param zipFilePath 压缩包中的文件夹路径
+     * @throws IOException
+     */
+    private static void handDirectory(File dir, ZipOutputStream zipOut, String zipFilePath) throws IOException {
+        File[] files = dir.listFiles();
+        if (ArrayUtils.isEmpty(files)) {
+            ZipEntry zipEntry = new ZipEntry(zipFilePath + dir.getName() + File.separator);
+            zipOut.putNextEntry(zipEntry);
+            zipOut.closeEntry();
+            return;
+        }
+        for (File file : files) {
+            doCompressFile(file, zipOut, zipFilePath + dir.getName() + File.separator);
+        }
+    }
+
+    /**
+     * 获取压缩文件流
+     *
+     * @param documentList 需要压缩的文件集合
+     * @return ByteArrayOutputStream
+     */
+    public static OutputStream compressFile(List<FileInfo> documentList, OutputStream outputStream) {
+        Map<String, List<FileInfo>> documentMap = new HashMap<>();
+        documentMap.put("", documentList);
+        return compressFile(documentMap, outputStream);
+    }
+
+    /**
+     * 将文件打包到zip
+     *
+     * @param documentMap 需要下载的附件集合 map的key对应zip里的文件夹名
+     * @return ByteArrayOutputStream
+     */
+    public static OutputStream compressFile(Map<String, List<FileInfo>> documentMap, OutputStream outputStream) {
+        CheckedOutputStream checkedOutputStream = new CheckedOutputStream(outputStream, new CRC32());
+        ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream);
+        try {
+            for (Map.Entry<String, List<FileInfo>> documentListEntry : documentMap.entrySet()) {
+                String dirName = documentMap.size() > 1 ? documentListEntry.getKey() : "";
+                Map<String, Integer> fileNameToLen = new HashMap<>();//记录单个合同号文件夹下每个文件名称出现的次数(对重复文件名重命名)
+                for (FileInfo document : documentListEntry.getValue()) {
+                    try {
+                        //防止单个文件夹下文件名重复 对重复的文件进行重命名
+                        String documentName = document.getFileName();
+                        if (fileNameToLen.get(documentName) == null) {
+                            fileNameToLen.put(documentName, 1);
+                        } else {
+                            int fileLen = fileNameToLen.get(documentName) + 1;
+                            fileNameToLen.put(documentName, fileLen);
+                            documentName = documentName + "(" + fileLen + ")";
+                        }
+                        String fileName = documentName + "." + document.getSuffix();
+                        if (StringUtils.isNotBlank(dirName)) {
+                            fileName = dirName + File.separator + fileName;
+                        }
+                        addCompressFile(document.getFileInputStream(), fileName, zipOutputStream);
+                    } catch (Exception e) {
+                        logger.info("filesToZip exception :", e);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.error("filesToZip exception:" + e.getMessage(), e);
+        }
+        return outputStream;
+    }
+
+    /**
+     * 将单个文件写入文件压缩包
+     *
+     * @param inputStream     文件输入流
+     * @param fileName        文件在压缩包中的相对全路径
+     * @param zipOutputStream 压缩包输出流
+     */
+    private static void addCompressFile(InputStream inputStream, String fileName, ZipOutputStream zipOutputStream) {
+        try (BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {
+            ZipEntry zipEntry = new ZipEntry(fileName);
+            zipOutputStream.putNextEntry(zipEntry);
+            byte[] bytes = new byte[1024];
+            int length;
+            while ((length = bufferedInputStream.read(bytes)) >= 0) {
+                zipOutputStream.write(bytes, 0, length);
+                zipOutputStream.flush();
+            }
+            zipOutputStream.closeEntry();
+        } catch (Exception e) {
+            logger.info("addFileToZip exception:", e);
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 通过网络请求下载zip
+     *
+     * @param sourceFilePath       需要压缩的文件路径
+     * @param response            HttpServletResponse
+     * @param zipName            压缩包名称
+     * @throws IOException
+     */
+    public static void httpDownloadCompressFile(String sourceFilePath, HttpServletResponse response, String zipName) throws IOException {
+        File sourceFile = new File(sourceFilePath);
+        if (!sourceFile.exists()) {
+            throw new RuntimeException(sourceFilePath + "不存在!");
+        }
+        if(StringUtils.isBlank(zipName)){
+            zipName = sourceFile.getName();
+        }
+        try (ServletOutputStream servletOutputStream = response.getOutputStream()){
+            CompressUtil.compressFile(sourceFile, servletOutputStream);
+            response.setContentType("application/zip");
+            response.setHeader("Content-Disposition", "attachment; filename=\"" + zipName + ".zip\"");
+            servletOutputStream.flush();
+        }
+    }
+
+    public static void httpDownloadCompressFileOld(String sourceFilePath, HttpServletResponse response, String zipName) throws IOException {
+        try (ServletOutputStream servletOutputStream = response.getOutputStream()){
+            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+            byte[] zipBytes = byteArrayOutputStream.toByteArray();
+            response.setContentType("application/zip");
+            response.setHeader("Content-Disposition", "attachment; filename=\"" + zipName + ".zip\"");
+            response.setContentLength(zipBytes.length);
+            servletOutputStream.write(zipBytes);
+            servletOutputStream.flush();
+        }
+    }
+
+    /**
+     * 通过网络请求下载zip
+     *
+     * @param sourceFilePath       需要压缩的文件路径
+     * @param response            HttpServletResponse
+     * @throws IOException
+     */
+    public static void httpDownloadCompressFile(String sourceFilePath, HttpServletResponse response) throws IOException {
+        httpDownloadCompressFile(sourceFilePath, response, null);
+    }
+
+
+    /**
+     * 检查文件名是否已经存在,如果存在,就在文件名后面加上“(1)”,如果文件名“(1)”也存在,则改为“(2)”,以此类推。如果文件名不存在,就直接创建一个新文件。
+     *
+     * @param filename 文件名
+     * @return File
+     */
+    public static File createNewFile(String filename) {
+        File file = new File(filename);
+        if (!file.exists()) {
+            try {
+                file.createNewFile();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        } else {
+            String base = filename.substring(0, filename.lastIndexOf("."));
+            String ext = filename.substring(filename.lastIndexOf("."));
+            int i = 1;
+            while (true) {
+                String newFilename = base + "(" + i + ")" + ext;
+                file = new File(newFilename);
+                if (!file.exists()) {
+                    try {
+                        file.createNewFile();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                    break;
+                }
+                i++;
+            }
+        }
+        return file;
+    }
+}

+ 21 - 0
src/main/java/com/example/poiaddr/util/ZipUnit/FileInfo.java

@@ -0,0 +1,21 @@
+package com.example.poiaddr.util.ZipUnit;
+
+import lombok.Data;
+
+import java.io.InputStream;
+
+/**
+ * @author fhey
+ * @date 2023-05-11 21:01:26
+ * @description: TODO
+ */
+@Data
+public class FileInfo {
+    private InputStream fileInputStream;
+
+    private String suffix;
+
+    private String fileName;
+
+    private boolean isDirectory;
+}

+ 46 - 0
src/main/java/com/example/poiaddr/util/dms/login.java

@@ -0,0 +1,46 @@
+package com.example.poiaddr.util.dms;
+
+import com.example.poiaddr.util.RequestUtils;
+import org.json.simple.JSONObject;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class login {
+    public static String DmsToken;
+
+    //  登录操作,请求token
+    public static String getDmsToken() {
+        JSONObject resultObject = RequestUtils.requestPost("http://121.43.55.7:2101/proxy_oauth/user/login?userName=user001&password=1234567890&clientId=2", null, null);
+        if (resultObject != null && resultObject.containsKey("message") && resultObject.get("message") != null) {
+            DmsToken = resultObject.get("message").toString();
+        }
+        return DmsToken;
+    }
+
+    public static JSONObject selectDms(String columnId) {
+        Map<String, String> headers = new HashMap<>();
+        if (DmsToken != null && DmsToken.length() > 0) {
+            headers.put("Token", DmsToken);
+        } else {
+            headers.put("Token", getDmsToken());
+        }
+        Map<String, String> formDatas = new HashMap<>();
+        formDatas.put("columnId", columnId);
+        formDatas.put("states", "0");
+        formDatas.put("pageSize", "9999");
+        formDatas.put("page", "0");
+        return RequestUtils.requestPost("http://121.43.55.7:2101/proxy_dms/content/selectContentList", headers, formDatas);
+    }
+
+    public static JSONObject addContent(Map<String, String> formDatas){
+        Map<String, String> headers = new HashMap<>();
+        if (DmsToken != null && DmsToken.length() > 0) {
+            headers.put("Token", DmsToken);
+        } else {
+            headers.put("Token", getDmsToken());
+        }
+        return RequestUtils.requestPost("http://121.43.55.7:2101/proxy_dms/content/addContent", headers, formDatas);
+    }
+}

+ 388 - 0
src/main/java/com/example/poiaddr/util/geotools/GeoHelpScript.java

@@ -0,0 +1,388 @@
+package com.example.poiaddr.util.geotools;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
+import java.math.BigDecimal;
+
+/**
+ * 坐标系转换工具
+ */
+public class GeoHelpScript {
+    /**
+     * 常量定义
+     */
+    private final Double PI = Math.PI;
+    private final Double x_PI = (PI * 3000.0) / 180.0;
+    private final Double ee = 0.00669342162296594323;
+    private final Double a = 6378245.0;
+
+    /**
+     * 主运行方法
+     * geoJson格式坐标系转换
+     * @param fileDataStr  geoJson字符串
+     * @param selectValue  转换前的坐标系名称 {"WGS84(国际通用)", "GCJ02(高德、QQ地图)", "BD09(百度地图)", "上海2000坐标系"}
+     * @param selectValue2 转换后的坐标系名称 {"WGS84(国际通用)", "GCJ02(高德、QQ地图)", "BD09(百度地图)", "上海2000坐标系"}
+     * @return JSONObject
+     * 转换前的坐标系名称和转换后的坐标系名称不能一样
+     */
+    public JSONObject run(String fileDataStr, String selectValue, String selectValue2) {
+        JSONObject fileData = JSONObject.parseObject(fileDataStr);
+            JSONArray features = fileData.getJSONArray("features");
+            for (int i = 0; i < features.size(); i++) {
+                JSONObject feature = (JSONObject) features.get(i);
+                JSONObject geometry = feature.getJSONObject("geometry");
+                JSONArray coordinates = geometry.getJSONArray("coordinates");
+                CoordinateSystemTransformation(coordinates, selectValue, selectValue2);
+            }
+        return fileData;
+    }
+
+    /**
+     * shp格式的坐标系转换
+     * @param fileDataStr shp文件数据
+     * @param selectValue 转换前坐标系 {"WGS84(国际通用)", "GCJ02(高德、QQ地图)", "BD09(百度地图)", "上海2000坐标系"}
+     * @param selectValue2 转换后坐标系 {"WGS84(国际通用)", "GCJ02(高德、QQ地图)", "BD09(百度地图)", "上海2000坐标系"}
+     * @return JSONArray
+     */
+    public JSONArray runShp(String fileDataStr, String selectValue, String selectValue2) {
+        JSONArray fileData = JSONArray.parseArray(fileDataStr);
+        for (int i = 0; i < fileData.size(); i++) {
+            JSONObject feature = fileData.getJSONObject(i);
+            if(feature.containsKey("fileName") && feature.containsKey("dataList")){
+                //      如果是geoJson的zip包格式
+                JSONArray dataList = feature.getJSONArray("dataList");
+                for (int j = 0; j < dataList.size(); j++) {
+                    JSONObject feature2 = dataList.getJSONObject(j);
+                    JSONObject geometry = feature2.getJSONObject("geometry");
+                    JSONArray coordinates = geometry.getJSONArray("coordinates");
+//                  坐标系转换
+                    CoordinateSystemTransformation(coordinates, selectValue, selectValue2);
+                }
+            }else{
+                JSONObject geometry = feature.getJSONObject("geometry");
+                JSONArray coordinates = geometry.getJSONArray("coordinates");
+//                坐标系转换
+                CoordinateSystemTransformation(coordinates, selectValue, selectValue2);
+            }
+        }
+        return fileData;
+    }
+
+    /**
+     * 迭代遍历 coordinates并转换坐标
+     *
+     * @param coordinates
+     */
+    public void CoordinateSystemTransformation(JSONArray coordinates, String selectValue, String selectValue2) {
+        if (coordinates.get(0) instanceof BigDecimal) {
+            Double[] outData;
+            if ("WGS84".equals(selectValue)) {
+                switch (selectValue2) {
+                    case "GCJ02":
+                        outData = wgs84_to_gcj02(coordinates.getDouble(0), coordinates.getDouble(1));
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                    case "BD09":
+                        outData = wgs84_to_bd09(coordinates.getDouble(0), coordinates.getDouble(1));
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                    case "SH2000":
+                        outData = wgs84_to_shcj(coordinates.getDouble(0), coordinates.getDouble(1));
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                }
+            } else if ("GCJ02".equals(selectValue)) {
+                switch (selectValue2) {
+                    case "WGS84":
+                        outData = gcj02_to_wgs84(coordinates.getDouble(0), coordinates.getDouble(1));
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                    case "BD09":
+                        outData = gcj02_to_bd09(coordinates.getDouble(0), coordinates.getDouble(1));
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                    case "SH2000":
+                        outData = gcj02_to_shcj(coordinates.getDouble(0), coordinates.getDouble(1));
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                }
+            } else if ("BD09".equals(selectValue)) {
+                switch (selectValue2) {
+                    case "WGS84":
+                        outData = bd09_to_wgs84(coordinates.getDouble(0), coordinates.getDouble(1));
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                    case "GCJ02":
+                        outData = bd09_to_gcj02(coordinates.getDouble(0), coordinates.getDouble(1));
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                    case "SH2000":
+                        Double[] lngLat = bd09_to_wgs84(coordinates.getDouble(0), coordinates.getDouble(1));
+                        outData = wgs84_to_shcj(lngLat[0], lngLat[1]);
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                }
+            } else if ("SH2000".equals(selectValue)) {
+                switch (selectValue2) {
+                    case "WGS84":
+                        outData = shcj_to_wgs84(coordinates.getDouble(0), coordinates.getDouble(1));
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                    case "BD09":
+                        Double[] lngLat = shcj_to_wgs84(coordinates.getDouble(0), coordinates.getDouble(1));
+                        outData = wgs84_to_bd09(lngLat[0], lngLat[1]);
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                    case "GCJ02":
+                        outData = shcj_to_gcj02(coordinates.getDouble(0), coordinates.getDouble(1));
+                        coordinates.set(0, outData[0]);
+                        coordinates.set(1, outData[1]);
+                        break;
+                }
+            }
+        } else {
+            for (int i = 0; i < coordinates.size(); i++) {
+                JSONArray coordinate = coordinates.getJSONArray(i);
+                CoordinateSystemTransformation(coordinate, selectValue, selectValue2);
+            }
+        }
+    }
+
+    public Double[] wgs84_to_gcj02(Double lng, Double lat) {
+        if (out_of_china(lng, lat)) {
+            return new Double[]{lng, lat};
+        } else {
+            double dlat = transformlat(lng - 105.0, lat - 35.0);
+            double dlng = transformlng(lng - 105.0, lat - 35.0);
+            double radlat = (lat / 180.0) * PI;
+            double magic = Math.sin(radlat);
+            magic = 1 - ee * magic * magic;
+            double sqrtmagic = Math.sqrt(magic);
+            dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
+            dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
+            Double[] gg = new Double[2];
+            gg[0] = lng + dlng;
+            gg[1] = lat + dlat;
+            return gg;
+        }
+    }
+
+    public Double[] gcj02_to_wgs84(Double lng, Double lat) {
+        if (out_of_china(lng, lat)) {
+            return new Double[]{lng, lat};
+        } else {
+            double dlat = transformlat(lng - 105.0, lat - 35.0);
+            double dlng = transformlng(lng - 105.0, lat - 35.0);
+            double radlat = (lat / 180.0) * PI;
+            double magic = Math.sin(radlat);
+            magic = 1 - ee * magic * magic;
+            double sqrtmagic = Math.sqrt(magic);
+            dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
+            dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
+            Double[] gg = new Double[2];
+            gg[0] = lng - dlng;
+            gg[1] = lat - dlat;
+            return gg;
+        }
+    }
+
+
+    public Double[] wgs84_to_shcj(Double x, Double y) {
+        Double[] xy = shcj_get_UTM_from_WGS(x, y);
+        return utm_to_shcj4(xy[0], xy[1]);
+    }
+
+    public Double[] shcj_to_wgs84(Double x, Double y) {
+        Double[] xy = shcj_to_utm4(x, y);
+        return shcj_get_WGS_from_UTM(xy[0], xy[1]);
+    }
+
+    public Double[] wgs84_to_bd09(Double x, Double y) {
+        Double[] xy = wgs84_to_gcj02(x, y);
+        return gcj02_to_bd09(xy[0], xy[1]);
+    }
+
+    public Double[] bd09_to_wgs84(Double x, Double y) {
+        Double[] xy = bd09_to_gcj02(x, y);
+        return gcj02_to_wgs84(xy[0], xy[1]);
+    }
+
+    public Double[] gcj02_to_shcj(Double x, Double y) {
+        Double[] xy = gcj02_to_wgs84(x, y);
+        return wgs84_to_shcj(xy[0], xy[1]);
+    }
+
+    public Double[] shcj_to_gcj02(Double x, Double y) {
+        Double[] xy = shcj_to_wgs84(x, y);
+        return wgs84_to_gcj02(xy[0], xy[1]);
+    }
+
+    public Double[] shcj_to_utm4(Double x, Double y) {
+        double DX, DY, T, K;
+        DX = 499999.90104;
+        DY = 3455696.403019;
+        T = -0.0000001755;
+        K = 0.999600149344;
+        return covert_by_four_parm(x, y, DX, DY, T, K);
+    }
+
+    public Double[] utm_to_shcj4(Double x, Double y) {
+        double DX, DY, T, K;
+        DX = -500199.29965;
+        DY = -3457078.805985;
+        T = 0.0000001755;
+        K = 1.0004000106;
+        return covert_by_four_parm(x, y, DX, DY, T, K);
+    }
+
+    public Double[] bd09_to_gcj02(Double bd_lon, Double bd_lat) {
+        Double x = bd_lon - 0.0065;
+        Double y = bd_lat - 0.006;
+        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
+        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
+        double gg_lng = z * Math.cos(theta);
+        double gg_lat = z * Math.sin(theta);
+        Double[] gg = new Double[2];
+        gg[0] = gg_lng;
+        gg[1] = gg_lat;
+        return gg;
+    }
+
+    public Double[] gcj02_to_bd09(Double lng, Double lat) {
+        double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
+        double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
+        Double[] gg = new Double[2];
+        gg[0] = z * Math.cos(theta) + 0.0065;
+        gg[1] = z * Math.sin(theta) + 0.006;
+        return gg;
+    }
+
+    public Boolean out_of_china(Double lng, Double lat) {
+        // 纬度3.86~53.55,经度73.66~135.05
+        return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
+    }
+
+
+    public double transformlat(Double lng, Double lat) {
+        double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
+        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
+        ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;
+        ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;
+        return ret;
+    }
+
+    public double transformlng(Double lng, Double lat) {
+        double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat +
+                0.1 * Math.sqrt(Math.abs(lng));
+        ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
+        ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0;
+        ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0;
+        return ret;
+    }
+
+    //四参数公式
+    public Double[] covert_by_four_parm(Double x, Double y, Double dx, Double dy, Double a, Double k) {
+        double px = 0;
+        double py = 0;
+        px = x * k * Math.cos(a) - y * k * Math.sin(a) + dx;
+        py = x * k * Math.sin(a) + y * k * Math.cos(a) + dy;
+        Double[] gg = new Double[2];
+        gg[0] = px;
+        gg[1] = py;
+        return gg;
+    }
+
+    public Double[] shcj_get_UTM_from_WGS(Double lon, Double lat) {
+        double a = 6378137;
+        double b = 6356752.3142451;
+        double f = (a - b) / a;
+
+        double eSquare = 2 * f - f * f;
+        double k0 = 0.9996;
+        double lonOrigin = 121.46714714;
+        double FN = 0;
+        // # 确保longtitude位于-180.00----179.9之间
+        double lonTemp = lon + 180 - Math.floor((lon + 180) / 360) * 360 - 180;
+        double latRad = (lat * PI) / 180;
+        double lonRad = (lonTemp * PI) / 180;
+        double lonOriginRad = (lonOrigin * PI) / 180;
+        double e2Square = eSquare / (1 - eSquare);
+
+        double V = a / Math.sqrt(1 - eSquare * Math.pow(Math.sin(latRad), 2));
+        double T = Math.pow(Math.tan(latRad), 2);
+        double C = e2Square * Math.pow(Math.cos(latRad), 2);
+        double A = Math.cos(latRad) * (lonRad - lonOriginRad);
+        double M = a * ((1 - eSquare / 4 - (3 * Math.pow(eSquare, 2)) / 64 - (5 * Math.pow(eSquare, 3)) / 256) * latRad - ((3 * eSquare) / 8 + (3 * Math.pow(eSquare, 2)) / 32 + (45 * Math.pow(eSquare, 3)) / 1024) * Math.sin(2 * latRad) + ((15 * Math.pow(eSquare, 2)) / 256 + (45 * Math.pow(eSquare, 3)) / 1024) * Math.sin(4 * latRad) - ((35 * Math.pow(eSquare, 3)) / 3072) * Math.sin(6 * latRad));
+
+        // # x
+        double UTMEasting = k0 * V * (A + ((1 - T + C) * Math.pow(A, 3)) / 6 + ((5 - 18 * T + Math.pow(T, 2) + 72 * C - 58 * e2Square) * Math.pow(A, 5)) / 120) + 500000.0;
+        //  # y
+        double UTMNorthing = k0 * (M + V * Math.tan(latRad) * (Math.pow(A, 2) / 2 + ((5 - T + 9 * C + 4 * Math.pow(C, 2)) * Math.pow(A, 4)) / 24 + ((61 - 58 * T + Math.pow(T, 2) + 600 * C - 330 * e2Square) * Math.pow(A, 6)) / 720));
+        //# 南半球纬度起点为10000000.0m
+        UTMNorthing += FN;
+        Double[] gg = new Double[2];
+        gg[0] = UTMEasting;
+        gg[1] = UTMNorthing;
+        return gg;
+    }
+
+
+    public Double[] shcj_get_WGS_from_UTM(Double x, Double y) {
+        //WGS84
+        double a = 6378137; //椭球体长半轴
+        double b = 6356752.3142451; //椭球体短半轴
+        x = 500000 - x;
+        double k0 = 0.9996;
+        double e = Math.sqrt(1 - Math.pow(b, 2) / Math.pow(a, 2));
+        // # calculate the meridional arc
+        double M = y / k0;
+        //# calculate footprint latitude
+        double mu = M / (a * (1 - Math.pow(e, 2) / 4 - (3 * Math.pow(e, 4)) / 64 - (5 * Math.pow(e, 6)) / 256));
+        double e1 = (1 - Math.pow(1 - Math.pow(e, 2), 1.0 / 2)) / (1 + Math.pow(1 - Math.pow(e, 2), 1.0 / 2));
+
+        double J1 = (3 * e1) / 2 - (27 * Math.pow(e1, 3)) / 32;
+        double J2 = (21 * Math.pow(e1, 2)) / 16 - (55 * Math.pow(e1, 4)) / 32;
+        double J3 = (151 * Math.pow(e1, 3)) / 96;
+        double J4 = (1097 * Math.pow(e1, 4)) / 512;
+        double fp = mu + J1 * Math.sin(2 * mu) + J2 * Math.sin(4 * mu) + J3 * Math.sin(6 * mu) + J4 * Math.sin(8 * mu);
+
+        // # Calculate Latitude and Longitude
+
+        double e2 = Math.pow(e, 2) / (1 - Math.pow(e, 2));
+        double C1 = e2 * Math.pow(Math.cos(fp), 2);
+        double T1 = Math.pow(Math.tan(fp), 2);
+        double R1 = (a * (1 - Math.pow(e, 2))) / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 3.0 / 2);
+        //# This is the same as rho in the forward conversion formulas above, but calculated for fp instead of lat.
+        double N1 = a / Math.pow(1 - Math.pow(e * Math.sin(fp), 2), 1.0 / 2);
+        //# This is the same as nu in the forward conversion formulas above, but calculated for fp instead of lat.
+        double D = x / (N1 * k0);
+
+        double Q1 = (N1 * Math.tan(fp)) / R1;
+        double Q2 = Math.pow(D, 2) / 2;
+        double Q3 = ((5 + 3 * T1 + 10 * C1 - 4 * Math.pow(C1, 2) - 9 * e2) * Math.pow(D, 4)) / 24;
+        double Q4 = ((61 + 90 * T1 + 298 * C1 + 45 * Math.pow(T1, 2) - 3 * Math.pow(C1, 2) - 252 * e2) * Math.pow(D, 6)) / 720;
+        double lat = ((fp - Q1 * (Q2 - Q3 + Q4)) * 180) / PI;
+        // System.out.println("lat===="+Math.toRadians(fp - Q1*(Q2 - Q3 + Q4)));
+        double Q5 = D;
+        double Q6 = ((1 + 2 * T1 + C1) * Math.pow(D, 3)) / 6;
+        double Q7 = ((5 - 2 * C1 + 28 * T1 - 3 * Math.pow(C1, 2) + 8 * e2 + 24 * Math.pow(T1, 2)) * Math.pow(D, 5)) / 120;
+        double lonmid = 121.46714714;
+        double lon = lonmid - (((Q5 - Q6 + Q7) / Math.cos(fp)) * 180) / PI;
+        Double[] gg = new Double[2];
+        gg[0] = lon;
+        gg[1] = lat;
+        return gg;
+    }
+}

+ 41 - 0
src/main/java/com/example/poiaddr/util/geotools/GeoJsonPointInRegion.java

@@ -0,0 +1,41 @@
+package com.example.poiaddr.util.geotools;import com.fasterxml.jackson.databind.ObjectMapper;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.io.ParseException;
+import java.io.IOException;
+
+/**
+ * 根据经纬度和geojson字符串,判断是否是包含关系
+ */
+public class GeoJsonPointInRegion {
+
+    public static boolean isPointInGeoJsonRegion(String geoJson, double longitude, double latitude) throws IOException, ParseException {
+        ObjectMapper mapper = new ObjectMapper();
+        // 将GeoJSON字符串解析成Geometry对象
+        Geometry geo = mapper.readValue(geoJson, Geometry.class);
+
+        GeometryFactory geometryFactory = new GeometryFactory();
+        // 创建表示点的Geometry对象
+        Coordinate point = new Coordinate(longitude, latitude);
+        Geometry pointGeom = geometryFactory.createPoint(point);
+
+        return geo.contains(pointGeom);
+    }
+
+    public static void main(String[] args) {
+        String sampleGeoJson = "{\"type\":\"Polygon\",\"coordinates\":[[[116.3,39.9],[116.4,39.9],[116.4,40.0],[116.3,40.0],[116.3,39.9]]]}";
+        double lon = 116.35;
+        double lat = 39.95;
+        try {
+            boolean result = isPointInGeoJsonRegion(sampleGeoJson, lon, lat);
+            if (result) {
+                System.out.println("点在区域内");
+            } else {
+                System.out.println("点不在区域内");
+            }
+        } catch (IOException | ParseException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 56 - 0
src/main/java/com/example/poiaddr/util/geotools/GeometryIntersectionAndDisjoint.java

@@ -0,0 +1,56 @@
+package com.example.poiaddr.util.geotools;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.io.ParseException;
+import org.locationtech.jts.io.WKTReader;
+
+/**
+ * 创建 GeometryFactory 和 WKTReader:
+ * GeometryFactory 用于创建各种几何对象。
+ * WKTReader 用于将 Well-Known Text (WKT) 格式的字符串转换为 Geometry 对象。
+ * 定义几何对象:
+ * 这里使用 WKT 字符串来表示几何对象。wkt1 和 wkt2 分别表示两个多边形。你可以根据需要修改这些字符串,它们可以是任何支持的几何类型,如 POINT、LINESTRING、POLYGON 等。
+ * 将 WKT 字符串解析为 Geometry 对象:
+ * 使用 wktReader.read(wkt) 方法将 WKT 字符串转换为 Geometry 对象。
+ * 相交判断:
+ * geometry1.intersects(geometry2) 方法用于判断 geometry1 和 geometry2 是否相交。
+ * 如果相交,返回 true,否则返回 false。
+ * 相离判断:
+ * geometry1.disjoint(geometry2) 方法用于判断 geometry1 和 geometry2 是否相离。
+ * 如果相离,返回 true,否则返回 false。
+ */
+public class GeometryIntersectionAndDisjoint {
+
+    public static void main(String[] args) {
+        GeometryFactory geometryFactory = new GeometryFactory();
+        WKTReader wktReader = new WKTReader(geometryFactory);
+
+        try {
+            // 定义两个几何对象,这里使用 WKT 格式的字符串表示
+            String wkt1 = "POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))";
+            String wkt2 = "POLYGON((5 5, 5 15, 15 15, 15 5, 5 5))";
+
+            // 将 WKT 字符串解析为 Geometry 对象
+            Geometry geometry1 = wktReader.read(wkt1);
+            Geometry geometry2 = wktReader.read(wkt2);
+
+            // 判断两个几何对象是否相交
+            boolean intersects = geometry1.intersects(geometry2);
+            System.out.println("两个几何对象是否相交: " + intersects);
+
+            // 判断两个几何对象是否相离
+            boolean disjoint = geometry1.disjoint(geometry2);
+            System.out.println("两个几何对象是否相离: " + disjoint);
+
+            // 判断 geometry2 是否包含 geometry1
+            boolean containsReverse = geometry2.contains(geometry1);
+            System.out.println("geometry2 是否包含 geometry1: " + containsReverse);
+
+            // 计算几何对象的面积
+            double area = geometry2.getArea();
+            System.out.println("该几何对象的面积为: " + area);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 13 - 0
src/main/resources/application.properties

@@ -0,0 +1,13 @@
+server.port=8081
+server.servlet.context-path=/poiApi/
+spring.application.name=poiAddr
+# application.properties
+spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/postgres
+spring.datasource.username=postgres
+spring.datasource.password=WE176852439@lmx
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.show-sql=true
+
+
+zip_file_path: ${ZIP_FILE_PATH:C:/Users/Liumouren/Desktop/}
+zip_file_name: ${ZIP_FILE_NAME:outFile}

+ 13 - 0
src/test/java/com/example/poiaddr/PoiAddrApplicationTests.java

@@ -0,0 +1,13 @@
+package com.example.poiaddr;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class PoiAddrApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.