SQL SERVER 使用 高德地图逆地址解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL SERVER 使用 高德地图逆地址解析相关的知识,希望对你有一定的参考价值。

作者:卞功鑫  ,转载请保留http://www.cnblogs.com/BinBinGo/p/6973234.html

 

一般我们得到的经纬度信息为GPS信息,所以要使用高德地图的逆地址解析功能(即把经纬度信息转换为地址信息),先需要把GPS经纬度信息先转换为高德地图经纬度.

一 经纬度转换

高德提供了转换API接口

http://restapi.amap.com/v3/assistant/coordinate/convert?key=您的key&locations=116.481499,39.990475&coordsys=gps

使用些接口可以把GPS信息转换为高德经纬度信息.

 

二 使用高德逆地址解析功能

高德提供了API接口

http://restapi.amap.com/v3/geocode/regeo?key=您的key&location=116.481488,39.990464&poitype=商务写字楼&radius=1000&extensions=all&batch=false&roadlevel=0

可以把经纬度信息转换为地址信息

各参数使用方法见高德官方网站:http://lbs.amap.com/api/webservice/summary


以上内容为官方内容,接下来要实现的是. 这些功能怎么在SQL Server 中 实现 :

上篇文章介绍了

存储过程封装web service

但是想要完整的实现还需要很多工作要做:

 

  1 创建解析json函数

             

技术分享
CREATE FUNCTION dbo.parseJSON( @JSON NVARCHAR(MAX))

RETURNS @hierarchy TABLE

  (

   element_id INT IDENTITY(1, 1) NOT NULL, /* internal surrogate primary key gives the order of parsing and the list order */

   sequenceNo [int] NULL, /* the place in the sequence for the element */

   parent_ID INT,/* if the element has a parent then it is in this column. The document is the ultimate parent, so you can get the structure from recursing from the document */

   Object_ID INT,/* each list or object has an object id. This ties all elements to a parent. Lists are treated as objects here */

   NAME NVARCHAR(2000),/* the name of the object */

   StringValue NVARCHAR(MAX) NOT NULL,/*the string representation of the value of the element. */

   ValueType VARCHAR(10) NOT null /* the declared type of the value represented as a string in StringValue*/

  )

AS

BEGIN

  DECLARE

    @FirstObject INT, --the index of the first open bracket found in the JSON string

    @OpenDelimiter INT,--the index of the next open bracket found in the JSON string

    @NextOpenDelimiter INT,--the index of subsequent open bracket found in the JSON string

    @NextCloseDelimiter INT,--the index of subsequent close bracket found in the JSON string

    @Type NVARCHAR(10),--whether it denotes an object or an array

    @NextCloseDelimiterChar CHAR(1),--either a ‘}‘ or a ‘]‘

    @Contents NVARCHAR(MAX), --the unparsed contents of the bracketed expression

    @Start INT, --index of the start of the token that you are parsing

    @end INT,--index of the end of the token that you are parsing

    @param INT,--the parameter at the end of the next Object/Array token

    @EndOfName INT,--the index of the start of the parameter at end of Object/Array token

    @token NVARCHAR(200),--either a string or object

    @value NVARCHAR(MAX), -- the value as a string

    @SequenceNo int, -- the sequence number within a list

    @name NVARCHAR(200), --the name as a string

    @parent_ID INT,--the next parent ID to allocate

    @lenJSON INT,--the current length of the JSON String

    @characters NCHAR(36),--used to convert hex to decimal

    @result BIGINT,--the value of the hex symbol being parsed

    @index SMALLINT,--used for parsing the hex value

    @Escape INT --the index of the next escape character





  DECLARE @Strings TABLE /* in this temporary table we keep all strings, even the names of the elements, since they are ‘escaped‘ in a different way, and may contain, unescaped, brackets denoting objects or lists. These are replaced in the JSON string by 
tokens representing the string */

    (

     String_ID INT IDENTITY(1, 1),

     StringValue NVARCHAR(MAX)

    )

  SELECT--initialise the characters to convert hex to ascii

    @characters=0123456789abcdefghijklmnopqrstuvwxyz,

    @SequenceNo=0, --set the sequence no. to something sensible.

  /* firstly we process all strings. This is done because [{} and ] aren‘t escaped in strings, which complicates an iterative parse. */

    @parent_ID=0;

  WHILE 1=1 --forever until there is nothing more to do

    BEGIN

      SELECT

        @start=PATINDEX(%[^a-zA-Z]["]%, @json collate SQL_Latin1_General_CP850_Bin);--next delimited string

      IF @start=0 BREAK --no more so drop through the WHILE loop

      IF SUBSTRING(@json, @start+1, 1)="

        BEGIN --Delimited Name

          SET @start=@Start+1;

          SET @end=PATINDEX(%[^\\]["]%, RIGHT(@json, LEN(@json+|)-@start) collate SQL_Latin1_General_CP850_Bin);

        END

      IF @end=0 --no end delimiter to last string

        BREAK --no more

      SELECT @token=SUBSTRING(@json, @start+1, @end-1)

      --now put in the escaped control characters

      SELECT @token=REPLACE(@token, FROMString, TOString)

      FROM

        (SELECT

          \\" AS FromString, " AS ToString

         UNION ALL SELECT \\\\, \\

         UNION ALL SELECT \\/, /

         UNION ALL SELECT \\b, CHAR(08)

         UNION ALL SELECT \\f, CHAR(12)

         UNION ALL SELECT \\n, CHAR(10)

         UNION ALL SELECT \\r, CHAR(13)

         UNION ALL SELECT \\t, CHAR(09)

        ) substitutions

      SELECT @result=0, @escape=1

  --Begin to take out any hex escape codes

      WHILE @escape>0

        BEGIN

          SELECT @index=0,

          --find the next hex escape sequence

          @escape=PATINDEX(%\\x[0-9a-f][0-9a-f][0-9a-f][0-9a-f]%, @token collate SQL_Latin1_General_CP850_Bin)

          IF @escape>0 --if there is one

            BEGIN

              WHILE @index<4 --there are always four digits to a \\x sequence  

                BEGIN

                  SELECT --determine its value

                    @result=@result+POWER(16, @index)

                    *(CHARINDEX(SUBSTRING(@token, @escape+2+3-@index, 1),

                                @characters)-1), @index=@index+1 ;



                END

                -- and replace the hex sequence by its unicode value

              SELECT @token=STUFF(@token, @escape, 6, NCHAR(@result))

            END

        END

      --now store the string away

      INSERT INTO @Strings (StringValue) SELECT @token

      -- and replace the string with a token

      SELECT @JSON=STUFF(@json, @start, @end+1,

                    @string+CONVERT(NVARCHAR(5), @@identity))

    END

  -- all strings are now removed. Now we find the first leaf. 

  WHILE 1=1  --forever until there is nothing more to do

  BEGIN



  SELECT @parent_ID=@parent_ID+1

  --find the first object or list by looking for the open bracket

  SELECT @FirstObject=PATINDEX(%[{[[]%, @json collate SQL_Latin1_General_CP850_Bin)--object or array

  IF @FirstObject = 0 BREAK

  IF (SUBSTRING(@json, @FirstObject, 1)={)

    SELECT @NextCloseDelimiterChar=}, @type=object

  ELSE

    SELECT @NextCloseDelimiterChar=], @type=array

  SELECT @OpenDelimiter=@firstObject



  WHILE 1=1 --find the innermost object or list...

    BEGIN

      SELECT

        @lenJSON=LEN(@JSON+|)-1

  --find the matching close-delimiter proceeding after the open-delimiter

      SELECT

        @NextCloseDelimiter=CHARINDEX(@NextCloseDelimiterChar, @json,

                                      @OpenDelimiter+1)

  --is there an intervening open-delimiter of either type

      SELECT @NextOpenDelimiter=PATINDEX(%[{[[]%,

             RIGHT(@json, @lenJSON-@OpenDelimiter)collate SQL_Latin1_General_CP850_Bin)--object

      IF @NextOpenDelimiter=0

        BREAK

      SELECT @NextOpenDelimiter=@NextOpenDelimiter+@OpenDelimiter

      IF @NextCloseDelimiter<@NextOpenDelimiter

        BREAK

      IF SUBSTRING(@json, @NextOpenDelimiter, 1)={

        SELECT @NextCloseDelimiterChar=}, @type=object

      ELSE

        SELECT @NextCloseDelimiterChar=], @type=array

      SELECT @OpenDelimiter=@NextOpenDelimiter

    END

  ---and parse out the list or name/value pairs

  SELECT

    @contents=SUBSTRING(@json, @OpenDelimiter+1,

                        @NextCloseDelimiter-@OpenDelimiter-1)

  SELECT

    @JSON=STUFF(@json, @OpenDelimiter,

                @NextCloseDelimiter-@OpenDelimiter+1,

                @+@type+CONVERT(NVARCHAR(5), @parent_ID))

  WHILE (PATINDEX(%[[email protected]+.e]%, @contents collate SQL_Latin1_General_CP850_Bin))<>0

    BEGIN

      IF @Type=Object --it will be a 0-n list containing a string followed by a string, number,boolean, or null

        BEGIN

          SELECT

            @SequenceNo=0,@end=CHARINDEX(:,  +@contents)--if there is anything, it will be a string-based name.

          SELECT  @start=PATINDEX(%[^[email protected]][@]%,  +@contents collate SQL_Latin1_General_CP850_Bin)--AAAAAAAA

          SELECT @token=SUBSTRING( +@contents, @start+1, @End-@Start-1),

            @endofname=PATINDEX(%[0-9]%, @token collate SQL_Latin1_General_CP850_Bin),

            @param=RIGHT(@token, LEN(@token)-@endofname+1)

          SELECT

            @token=LEFT(@token, @endofname-1),

            @Contents=RIGHT( +@contents, LEN( +@contents+|)-@end-1)

          SELECT  @name=stringvalue FROM @strings

            WHERE string_id=@param --fetch the name

        END

      ELSE

        SELECT @Name=null,@SequenceNo=@SequenceNo+1

      SELECT

        @end=CHARINDEX(,, @contents)-- a string-token, object-token, list-token, number,boolean, or null

      IF @end=0

        SELECT  @end=PATINDEX(%[[email protected]+.e][^[email protected]+.e]%, @Contents+  collate SQL_Latin1_General_CP850_Bin)

          +1

       SELECT

        @start=PATINDEX(%[^[email protected]+.e][[email protected]+.e]%,  +@contents collate SQL_Latin1_General_CP850_Bin)

      --select @start,@end, LEN(@contents+‘|‘), @contents 

      SELECT

        @Value=RTRIM(SUBSTRING(@contents, @start, @End-@Start)),

        @Contents=RIGHT(@contents+ , LEN(@contents+|)-@end)

      IF SUBSTRING(@value, 1, 7)=@object

        INSERT INTO @hierarchy

          (NAME, SequenceNo, parent_ID, StringValue, Object_ID, ValueType)

          SELECT @name, @SequenceNo, @parent_ID, SUBSTRING(@value, 8, 5),

            SUBSTRING(@value, 8, 5), object

      ELSE

        IF SUBSTRING(@value, 1, 6)=@array

          INSERT INTO @hierarchy

            (NAME, SequenceNo, parent_ID, StringValue, Object_ID, ValueType)

            SELECT @name, @SequenceNo, @parent_ID, SUBSTRING(@value, 7, 5),

              SUBSTRING(@value, 7, 5), array

        ELSE

          IF SUBSTRING(@value, 1, 7)=@string

            INSERT INTO @hierarchy

              (NAME, SequenceNo, parent_ID, StringValue, ValueType)

              SELECT @name, @SequenceNo, @parent_ID, stringvalue, string

              FROM @strings

              WHERE string_id=SUBSTRING(@value, 8, 5)

          ELSE

            IF @value IN (true, false)

              INSERT INTO @hierarchy

                (NAME, SequenceNo, parent_ID, StringValue, ValueType)

                SELECT @name, @SequenceNo, @parent_ID, @value, boolean

            ELSE

              IF @value=null

                INSERT INTO @hierarchy

                  (NAME, SequenceNo, parent_ID, StringValue, ValueType)

                  SELECT @name, @SequenceNo, @parent_ID, @value, null

              ELSE

                IF PATINDEX(%[^0-9]%, @value collate SQL_Latin1_General_CP850_Bin)>0

                  INSERT INTO @hierarchy

                    (NAME, SequenceNo, parent_ID, StringValue, ValueType)

                    SELECT @name, @SequenceNo, @parent_ID, @value, real

                ELSE

                  INSERT INTO @hierarchy

                    (NAME, SequenceNo, parent_ID, StringValue, ValueType)

                    SELECT @name, @SequenceNo, @parent_ID, @value, int

      if @Contents=  Select @SequenceNo=0

    END

  END

INSERT INTO @hierarchy (NAME, SequenceNo, parent_ID, StringValue, Object_ID, ValueType)

  SELECT -,1, NULL, ‘‘, @parent_id-1, @type

--

   RETURN

END
View Code

     

   2  创建经纬度转换存储过程

 

技术分享
CREATE      PROC p_et_gps_convert

    (

      @log VARCHAR(80)

    , @lat VARCHAR(80)

    , @result VARCHAR(8000) OUTPUT
    )

AS

    DECLARE @ServiceUrl AS VARCHAR(1000); 
    DECLARE @UrlAddress VARCHAR(500);
---WebService地址:以http开头,结尾带斜杠,例如‘http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx/‘ 
    SET @UrlAddress = http://restapi.amap.com/v3/assistant/coordinate/;
  
  DECLARE @FunName VARCHAR(50);
---WebService中调用的方法名:例如‘getMobileCodeInfo‘
    SET @FunName = convert;   
---以下参数对应WebService中4个参数的[参数名]
    DECLARE @location VARCHAR(200)

      , @key VARCHAR(200)

      , @coordsys VARCHAR(20);


    SET @location = @log + , + @lat;
    SET @key = bgxbgxbgxbgxbgxbgx;
    SET @coordsys = gps;

    SET @ServiceUrl = @UrlAddress + @FunName + ?key= + @key + &locations=

        + @location + &coordsys= + @coordsys;                     
        
    DECLARE @Object AS INT;
    DECLARE @ResponseText AS VARCHAR(8000);
                  
    EXEC sp_OACreate MSXML2.XMLHTTP, @Object OUT;
    EXEC sp_OAMethod @Object, open, NULL, get, @ServiceUrl, false;
    EXEC sp_OAMethod @Object, send;
    EXEC sp_OAMethod @Object, responseText, @ResponseText OUTPUT;
     

    



    SELECT  @result = StringValue

    FROM    dbo.parseJSON(@ResponseText)

    WHERE   NAME = locations;


    EXEC sp_OADestroy @Object;
View Code

 

3 创建逆地址解析存储过程

 

技术分享
CREATE   PROC p_et_gps_geocode(@log VARCHAR(20),@lat VARCHAR(20),@result VARCHAR(8000) OUTPUT)
as 
DECLARE @ServiceUrl AS VARCHAR(1000); 
DECLARE @UrlAddress VARCHAR(500);
---WebService地址:以http开头,结尾带斜杠,例如‘http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx/‘ 
SET @UrlAddress = http://restapi.amap.com/v3/geocode/;
DECLARE @FunName VARCHAR(50);
---WebService中调用的方法名:例如‘getMobileCodeInfo‘
SET @FunName = regeo;   
---以下参数对应WebService中4个参数的[参数名]
DECLARE @output VARCHAR(20)
  , @location VARCHAR(200)
  , @key VARCHAR(200)
  , @radius VARCHAR(10)
  , @extensions VARCHAR(10);

  exec p_et_gps_convert @log,@lat,@location output

SET @output = json;
SET @key = bgxbgxbgxbgxbgxbgx;
SET @radius = 1000;
SET @extensions = base;
SET @ServiceUrl= @UrlAddress + @FunName + ?output= + @output + &location=
    + @location + &key= + @key + &radius= + @radius + &extensions=
    + @extensions;                     
        
DECLARE @Object AS INT;
DECLARE @ResponseText AS VARCHAR(8000);
                  
EXEC sp_OACreate MSXML2.XMLHTTP, @Object OUT;
EXEC sp_OAMethod @Object, open, NULL, get,@ServiceUrl, false;
EXEC sp_OAMethod @Object, send;
EXEC sp_OAMethod @Object, responseText, @ResponseText OUTPUT;
     
SET @result =  @ResponseText;     
EXEC sp_OADestroy @Object;
View Code

 

 

4 使用 之前创建的 解析函数查询就可以了.

 

DECLARE @info VARCHAR(max)
EXEC p_et_gps_geocode 112.226135,35.57848,@info OUTPUT
SELECT * FROM dbo.parseJSON( @info)

 

 

以上SQL SERVER 中 解决这些问题完全搞定. 

 

 

 

 

 

 

 

 

 








以上是关于SQL SERVER 使用 高德地图逆地址解析的主要内容,如果未能解决你的问题,请参考以下文章

Java百度地图高德地图ArcGIS地图逆地理编码

微信小程序 获取位置移动选点逆地址解析

高德地图javascriptAPI基本使用心得(下)

百度地图 逆地址解析

百度地图地址解析/逆地址解析

百度地图地址解析/逆地址解析