In questo link potete trovare l'articolo di Google che spiega algoritmo mentre una spiegazione più approfondita potete trovarla in questi due link Encoding algorithm e Description of encoded polylines di Mark McClure.
Inoltre sempre su Google potete testare direttamente online Interactive Polyline Encoder Utility
Nel progetto che vi ho allegato ho utilizzato il js PolylineEncoder che potete trovare qui.
In sintesi ho tradotto in c# la classe PolylineEncoder per poter creare le polilinee & poligoni anche lato server.
Lato server
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Web.Services;
using Microsoft.SqlServer.Types;
//Author: Domenico Ciavarella
//http://www.studioat.it
namespace GoogleEncode
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static List<List<double []>> GetPolygonEncodeClient()
{
List<List<double[]>> pts = new List<List<double []>>();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["GeoConnectionString"].ConnectionString))
{
conn.Open();
string sqlCommandText = "SELECT GEOM FROM LimitiComunali WHERE FID < 20";
using (SqlCommand sqlCommand = new SqlCommand(sqlCommandText, conn))
{
using (SqlDataReader sdr = sqlCommand.ExecuteReader())
{
while (sdr.Read())
{
pts.Add(GetPoints<List<double[]>, double[]>((SqlGeography)(sdr["GEOM"]),(d1,d2) => new double[2]{d1,d2}));
}
}
}
}
return pts;
}
[WebMethod]
public static Encode[] GetPolygonEncodeServer()
{
PolylineEncoder polylineEncoder = new PolylineEncoder();
IList<Encode> pts = new List<Encode>();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["GeoConnectionString"].ConnectionString))
{
conn.Open();
string sqlCommandText = "SELECT GEOM FROM LimitiComunali WHERE FID < 20";
using (SqlCommand sqlCommand = new SqlCommand(sqlCommandText, conn))
{
using (SqlDataReader sdr = sqlCommand.ExecuteReader())
{
while (sdr.Read())
{
pts.Add(polylineEncoder.DpEncode(GetPoints<List<Point>,Point>((SqlGeography)(sdr["GEOM"]),(d1,d2) => new Point(d1,d2)).ToArray<Point>()));
}
}
}
}
return pts.ToArray<Encode>();
}
public static T GetPoints<T,U>(SqlGeography sqlGeography, Func<double,double,U> ctor) where T :ICollection<U>, new()
{
SqlGeography sqlGeographyExterior = null;
T list = new T();
if (sqlGeography.NumRings().Value == 1)
{
sqlGeographyExterior = sqlGeography;
}
else
{
sqlGeographyExterior = sqlGeography.RingN(1);
}
SqlGeography sqlGeographyCurrent = null;
for (int i = 1; i <= sqlGeographyExterior.STNumPoints().Value; i++)
{
sqlGeographyCurrent = sqlGeographyExterior.STPointN(i);
list.Add(ctor(sqlGeographyCurrent.Long.Value, sqlGeographyCurrent.Lat.Value));
}
return list;
}
}
}
Lato client (decommenta PageMethods.GetPolygonEncodeClient o PageMethods.GetPolygonEncodeServer se rispettivamente vuoi codificare lato client o lato server)
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GoogleEncode._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
type="text/javascript"></script>
<script src ="js/PolylineEncoder.js" type="text/javascript"></script>
<script type="text/javascript">
var map = null;
function initialize() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map_canvas"));
var mapControl = new GMapTypeControl();
map.addControl(mapControl);
map.addControl(new GLargeMapControl());
var centerat = new GLatLng(45.52, 7.52);
map.setCenter(centerat, 10);
//build encode from client
PageMethods.GetPolygonEncodeClient(onCompleteGetPolygonEncodeClient, onFailureGetPolygonEncode);
//build encode from server
//PageMethods.GetPolygonEncodeServer(onCompleteGetPolygonEncodeServer, onFailureGetPolygonEncode);
}
}
function onCompleteGetPolygonEncodeServer(result, response, context) {
var plArray = new Array();
for (i = 0; i < result.length; i++) {
var polyline = { color: "#0000ff",
weight: 3,
opacity: 0.9,
points: result[i].EncodedPoints,
levels: result[i].EncodedLevels,
numLevels: 18,
zoomFactor: 2
};
Array.add(plArray, polyline);
}
var polygon = new GPolygon.fromEncoded({polylines: plArray, color: "#0000ff", opacity: 0.9, fill: true, outline: true });
map.addOverlay(polygon);
}
function onCompleteGetPolygonEncodeClient(result, response, context) {
var plArray = new Array();
var polygonEncoder = new PolylineEncoder();
for (i = 0; i < result.length; i++) {
var pts = PolylineEncoder.pointsToGLatLngs(result[i]);
var plJSON = polygonEncoder.dpEncodeToJSON(pts, "#0000ff", 3, 0.9);
Array.add(plArray, plJSON);
}
var polygon = new GPolygon.fromEncoded({ polylines: plArray, color: "#0000ff", opacity: 0.9, fill: true, outline: true });
map.addOverlay(polygon);
}
function onFailureGetPolygonEncode(objError) {
alert(objError.get_message());
}
function ColorRandom() {
return (Math.round(0xFFFFFF * Math.random()).toString(16) + "000000").replace(/([a-f0-9]{6}).+/, "#$1").toUpperCase();
}
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager" runat="server"
EnablePageMethods="true">
</asp:ScriptManager>
<div id="map_canvas" style="width: 800px; height: 600px"></div>
</form>
</body>
Nessun commento:
Posta un commento