jsp连接MySQL数据库显示GIS地理数据乱码问题的解决(select AsText(the_geom))
oh,fuck,经过我昨天下午到今天的努力,终于将这一问题成功解决了,哈哈哈
问题详细描述:
我通过jsp页面连接上MySQL数据库,取出存在表中的地理数据(类型是geometry,具体有POINT、MULTILINESTRING等),其在数据库中的存储格式为(以POINT类为例):POINT(121.38785 28.426766),表的设计及表内具体内容见下图:
前天就测试了把表中的全部数据取出来,但取出来之后发现经纬度部分是乱码的,由于我昨天先要解决jsp往数据库存数据乱码的问题,所以就先把经纬度乱码的问题放了一放。昨天下午终于把存数据乱码的问题解决了之后就开始考虑如何解决经纬度显示乱码的问题。
我首先想到的是,既然我存进数据库的是字符串(如POINT(121.38785 28.426766)),那么我取出来的也应该是字符串啊,因而也就应该能正常显示到页面啊。如果能正常显示的话,我就能使用字符串分离提取出经度值和纬度值来使用了。可是乱码问题出在哪儿呢?
在openlayers技术群1里问了下,有人提示我试试使用类似于SELECT X(GeometryFromText(P))、SELECT Y(GeometryFromText(P))的语句取the_geom的数值试下,我把p用the_geom替换,添加到我的jsp页面的语句中,测试,不可行,而且这样的话会对我的代码结构产生影响,并且会影响我的结果的输出,具体为什么请看我的代码结构(主要是我使用了String query_sql = "select * from biandianzhan_point_tb";这一语句):
String connUrl = "jdbc:mysql://localhost/" + DBName + "?user=" + DBUser + "&password=" + DBPasswd; Class.forName(driverName).newInstance(); Connection conn = DriverManager.getConnection(connUrl); Statement stmt = conn.createStatement(); stmt.executeQuery("SET NAMES UTF8"); String query_sql = "select * from biandianzhan_point_tb"; try { ResultSet rs = stmt.executeQuery(query_sql); while(rs.next()) { %> ID:<%=rs.getString("id")%> </br> 名称:<%=rs.getString("name")%> </br> 电压等级:<%=rs.getString("voltage_level")%> </br> 经纬度:<%=rs.getString("AsText(the_geom)")%> </br> <% } }catch(Exception e) { e.printStackTrace(); } //rs.close(); stmt.close(); conn.close();
群里的那位仁兄同时还给我发来MySQL官网中介绍MySQL对空间数据支持的扩展的API链接(http://dev.mysql.com/doc/refman/5.1/zh/spatial-extensions-in-mysql.html#fetching-spatial-data),我进去看了下,很有收获,最终锁定了一个函数AsText(),非常感谢这位仁兄啊!
但是,我自己尝试着使用了下这个函数,没测试成功,很遗憾。后来发现我是测试的对象不对,我测试的是age和name,这两个变量的类型和the_geom的类型不对,估计是AsText()函数指定了参数类型。测试的结果如下图:
因为我对AsText()这个函数不了解,不知道怎么正确使用,于是我在网上搜索了一下这个函数,遗憾的是可用资源太少,庆幸的是我找到了一片很有用的博客,在此非常感谢博主!博文的网址为http://blog.sina.com.cn/s/blog_a48af8c001018q1p.html,下面我摘抄了一段有用的内容:
从Points表中读取数据也是非常简单的:
SELECT name, AsText(location) FROM Points;
以上语句的返回结果中location会被转换成跟第二步中一样的GIS标准字符串。实际上AsText函数仅仅是把数据库内部存储的几何对象格式化成一个字符串而已。
下面一个函数也是非常有用的:
SELECT name, AsText(location) FROM Points WHERE X(location) < 10 and Y(location) > 12;
该Select语句返回一系列location的X()(经度)小于10并且Y()(经度)大于12的点集合。
空间表的高级查询
把指定的几何对象转变易读的文本:
SELECT AsText(Envelope(GeomFromText('LineString(1 1,2 2)')));
返回指定几何对象的大小:
SELECT GeometryType(GeomFromText('POINT(1 1)'));
返回指定几何对象的类型:
SELECT GeometryType(GeomFromText('POINT(1 1)'));
于是,我现在数据库命令行里测试了下命令:select AsText(the_geom) from biandianzhan_point_tb ,哈哈哈,成功地显示了我需要的字符串信息:经纬度。于是我又扩展了一下这个语句,改为:select id,name,voltage_level,AsText(the_geom) from biandianzhan_point_tb,呵呵,也成功地显示了目标信息,测试结果如下:
可以看出命令行显示的中文字符是乱码的,不过不要紧,这是命令行dos窗口的编码方式导致的。总的来说,我现在是非常高兴的,因为终于能够显示我想要的信息了。
接下来就是要把这些语句放进jsp页面代码中执行了,修改后,我的jsp代码为:
String connUrl = "jdbc:mysql://localhost/" + DBName + "?user=" + DBUser + "&password=" + DBPasswd;
Class.forName(driverName).newInstance();
Connection conn = DriverManager.getConnection(connUrl);
Statement stmt = conn.createStatement();
stmt.executeQuery("SET NAMES UTF8");
String insert_sql = "INSERT INTO biandianzhan_point_tb VALUES('" + id + "','" + name + "','" + voltage_level + "',GeometryFromText('POINT (" + lon + " " + lat + ")') )";
String query_sql = "select id,name,voltage_level,AsText(the_geom) from biandianzhan_point_tb";
try {
stmt.execute(insert_sql);
}catch(Exception e) {
e.printStackTrace();
}
try {
ResultSet rs = stmt.executeQuery(query_sql);
while(rs.next()) {
%>
ID:<%=rs.getString("id")%> </br>
名称:<%=rs.getString("name")%> </br>
电压等级:<%=rs.getString("voltage_level")%> </br>
经纬度:<%=rs.getString("AsText(the_geom)")%> </br> </br>
<%
}
}catch(Exception e) {
e.printStackTrace();
}
//rs.close();
stmt.close();
conn.close();
修改好后,直接在浏览器访问insert_map.jsp,见证奇迹的时刻就要到了啊!
哈哈,我期望的效果终于出来了啊!经纬度值终于显示了!
下一步我就可以使用字符串分离分别得到经度值和纬度值用于其他地方了。