现在的位置: 首页 > 综合 > 正文

用jscript读取base64编码的空间数据(提供一种js map api共享与开放空间数据的思路)

2011年12月23日 ⁄ 综合 ⁄ 共 6204字 ⁄ 字号 评论关闭

提供一种js map api共享与开放空间数据的思路

在客户端中把空间数据编码为base64的优势就不在此赘述,不了解这种编码方法的朋友可以参考相关资料。

sqlserver2k5中利用CLR-UDF实现空间查询一文中我举例了一个空间查询的sql语句,如果在其后追加

FOR XML AUTO, ELEMENTS, BINARY BASE64

一句,则sqlserver(2000以后就支持了)自动将查询结果以XML的方式输出,其中BLOB字段以BASE64编码的方式输出。

例如有一个geometry字段的节点为:

<geometry>
AgAAAAEAAABbI4JxcBJbQM1bdR2q1TZA
</geometry>

这是一个MultiPoint类型(这是一个用与举例的自定义格式,类似iso spatial schema。空间数据的存储格式有很多,如想实现数据共享,采用OGC的SFS无疑是最好的选择)的空间数据。其的格式如表示下
| MultiPoint类型 | 点的个数 | x1 , y1 | x2, y2 | ......|
类型用一个整数表示(本例中MulitPoint的值是2),占4个byte。点个数也是整型,也是4个字节。其后的坐标值为double型,占8个字节。
这个字符串“AgAAAAEAAABbI4JxcBJbQM1bdR2q1TZA”的数据为“2,1,108.288113,22.834627
其表示一个有一个点的MultiPoint类型,坐标为108.288113,22.834627。

从base64编码得到数据首先要对其进行解码,这很简单,但大家知道js的数据类型只有number型,它可以支持的很大(可以用alert(Number.MAX_VALUE)看看,是1.7976931348623157e+308)。但在进行位运算的时候,IE的js却只支持32位整数。这是在是太。。。FAINT了。。。也就是说,在IE的js中,不可能象数据类型完备的高级语言那样通过按位运算来求值。我当时几乎放弃了。。。。山重水复疑无路啊。。。还好,忽然发现了parseInt函数,总算找到那一村了。

具体不再废话,看代码吧:
(某些注释掉部分为关联其他js库,我已修改过,可不予理会)

  1 //**************************************************************************
  2 //      Copyright (c)  All rights reserved.
  3 //      File         : core.Base64Reader.js
  4 //      Author       : Edison1024, micro1024(a)gmail.com
  5 //        Description  : 
  6 //      Dependencies : 
  7 //      Date Created : 2005.10.11
  8 //--------------------------------------------------------------------------
  9 //      Date                 Modified By               Description
 10 //--------------------------------------------------------------------------
 11 //      
 12 //**************************************************************************
 13 
 14 
 15 function Base64Reader(base64String)
 16 {
 17     var _offset = 0;
 18     var _buffer = _base64Decode(base64String);
 19     
 20     function _base64Decode(input)
 21     {
 22         if((input.length % 4)!=0)
 23         {
 24             throw new Error("Invaild base64 encoding.");
 25             return;
 26         }
 27         var rgExp = new RegExp("^[A-Z0-9/+=]*$""g");
 28         if(/*!isNull(input.match(rgExp))*/input.match(rgExp) != null)
 29         {
 30             throw new Error("There were invalid base64 characters in the input string");
 31             return;
 32         }
 33         
 34         var base64Code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
 35         
 36         var output = new Array();
 37         var chr1, chr2, chr3;
 38         var enc1, enc2, enc3, enc4;
 39         var i = 0;
 40         
 41         do 
 42         {
 43             enc1 = base64Code.indexOf(input.charAt(i++));
 44             enc2 = base64Code.indexOf(input.charAt(i++));
 45             enc3 = base64Code.indexOf(input.charAt(i++));
 46             enc4 = base64Code.indexOf(input.charAt(i++));
 47 
 48             chr1 = (enc1 << 2| (enc2 >> 4);
 49             chr2 = ((enc2 & 15<< 4| (enc3 >> 2);
 50             chr3 = ((enc3 & 3<< 6| enc4;
 51 
 52             output.push(chr1);
 53             if (enc3 != 64)
 54             {
 55                 output.push(chr2); 
 56             }
 57             if (enc4 != 64)
 58             {
 59                 output.push(chr3); 
 60             }
 61 
 62             chr1 = chr2 = chr3 = "";
 63             enc1 = enc2 = enc3 = enc4 = "";
 64         } 
 65         while (i < input.length);
 66 
 67         return output;
 68     }
 69     
 70     /*JScript的数据类型局限,下面的算法是无法求出正确结果的。
 71     JScript没有long型,虽然他的number型可以很大,但经过我详细测,
 72     发现进行按位运算的时候却只支持32位整数。
 73     不知道ECMAScript规范的Scripting实现就是这样还是M$IE的Scripting的实现有问题。
 74     在NS和FF中我没测试过。
 75     */
 76     //function _byteToDouble(buffer)
 77     //{
 78     //    var l;
 79     //    l = buffer[0];
 80     //    l &= 0xff;
 81     //    l |= (buffer[1] << 8);
 82     //    l &= 0xffff;
 83     //    l |= (buffer[2] << 16);
 84     //    l &= 0xffffff;
 85     //    l |= (buffer[3] << 24);
 86     //    l &= 0xffffffff;
 87     //    l |= (buffer[4] << 32);
 88     //    l &= 0xffffffffff;
 89     //    l |= (buffer[5] << 40);
 90     //    l &= 0xffffffffffff;
 91     //    l |= (buffer[6] << 48);
 92     //    l &= 0xffffffffffffff;
 93     //    l |= (buffer[7] << 56);
 94 
 95     //    alert(l);
 96     //    
 97     //    var s = ((l >> 63) == 0) ? 1 : -1;
 98     //    var e = ((l >> 52) & 0x7ff);
 99     //    var m = (e == 0) ?
100     //                    (l & 0xfffffffffffff) << 1 :
101     //                    (l & 0xfffffffffffff) | 0x10000000000000;
102 
103     //    return s * m * Math.pow(2, (e - 1075));
104     //}
105 
106     /*这是我给出的实现,利用了parseInt()函数把二进制的字符串转成long型的数据,然后由公式求出double*/
107     function _byteToDouble(buffer, start, end)
108     {
109         if(/*buffer.getType() != "Array" || */(end - start) != 8)
110             throw new Error("Failed to read data invalid arguments error message");
111             
112         var longBits = "";
113         for(var i = start; i < end; i++)
114         {
115             var temp = buffer[i].toString(2);
116             while(temp.length < 8)
117             {
118                 temp = "0" + temp;
119             }
120             longBits = temp + longBits;
121         }
122         
123         var s = (longBits.substring(01== "0"? 1 : -1;
124         var e = (parseInt(longBits.substring(012), 2& 0x7ff);
125         var m = (e == 0?
126                         ("0000000000" + longBits.substring(1264+ "0") :
127                         ("00000000001" + longBits.substring(1264));
128         m = parseInt(m, 2);
129         
130         return s * m * Math.pow(2, (e - 1075));
131     }
132 
133 
134     function _byteToInt(buffer, start, end)
135     {
136         if(/*buffer.getType() != "Array" || */(end - start) != 4)
137             throw new Error("Failed to read data invalid arguments error message");
138             
139         var intBits = 0;
140         for(var i = end; i-- > start;)
141         {
142             intBits <<= 8;
143             intBits |= buffer[i] & 255;
144         }
145         return intBits;
146     }
147     
148     this.readInt = function()
149     {
150         return _byteToInt(_buffer, _offset, _offset += 4);
151     }
152     
153     this.readDouble = function()
154     {
155         return _byteToDouble(_buffer, _offset, _offset += 8);
156     }
157 }
158 
159 
160 

打包及测试文件下载
Base64Reader.rar

抱歉!评论已关闭.