无法反序列化GoogleMaps DirectionsResult对象

时间:2010-12-29 18:11:45

标签: javascript json google-maps serialization

我正在使用GoogleMaps API v3.0并尝试将DirectionsResult保存到我的数据库,然后稍后检索它以在地图上使用。我的问题是,当我尝试通过从我的数据库中提取其JSON表示来重新保存已保存的对象时,该对象只是简单的JSON,它没有其组成对象的原始方法和功能。因此,我构建了一个修复例程,它接受dumbalt文本JSON并通过重建所有LatLng和LatLngBound对象来重建它。但是,仍然缺少某些东西,因为我的固定物体不能像原物一样工作,这两个点出现在我的地图上,但它们之间的紫色线丢失了。

对于更好的序列化/保湿技术或任何关于我的修复程序可能缺失的想法,我们将不胜感激。

由于

alt text alt text

request = {
   origin: homeLocation, 
   destination: jobLocation,
   travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
   if (status == google.maps.DirectionsStatus.OK) {
      var str = Ext.encode(response);  //<<==SAVING RAW JSON OBJECT TO DB (I USE ExtJs)
      var z = eval('(' + str + ')');   //<<==REHYDRATING DirectionsResult RAW JSON OBJECT
      FixDirectionResult(z);           //<<==ATTEMPT TO RE-ESTABLISH ORIGINAL OBJECTS
      directionsRenderer.setDirections(z);  //<<==THIS WORKS WITH response BUT NOT WITH z
   }
);
function FixDirectionResult(rslt) {
 for(r=0; r<rslt.routes.length; r++) {
  var route = rslt.routes[r];
  var bounds = route.bounds;
  route.bounds = new google.maps.LatLngBounds(
   new google.maps.LatLng(bounds.U.b,bounds.O.d), 
   new google.maps.LatLng(bounds.U.d,bounds.O.b));

  for(l=0; l<route.legs.length;l++) {
   var leg = route.legs[l];
   leg.start_location = new google.maps.LatLng(leg.start_location.wa,leg.start_location.ya);
   leg.end_location = new google.maps.LatLng(leg.end_location.wa,leg.end_location.ya);

   for(s=0; s<leg.steps.length;s++) {
    var step = leg.steps[s];
    step.start_location = 
     new google.maps.LatLng(step.start_location.wa,step.start_location.ya);
    step.end_location = 
     new google.maps.LatLng(step.end_location.wa,step.end_location.ya);

    for(p=0;p<step.path.length;p++) {
     var path=step.path[p];
     step.path[p] = new google.maps.LatLng(step.path.wa,step.path.ya);
    }
   }
  }

  for(o=0; o<route.overview_path.length;o++) {
   var overview = route.overview_path[o];
   route.overview_path[o] = new google.maps.LatLng(overview.wa,overview.ya);
  }
 }
} 

4 个答案:

答案 0 :(得分:5)

从代码的外观来看,您似乎没有正确访问lat和lng。谷歌地图api库缩小了。变量名通常缩写为随机字符集。你不应该通过这些变量接近x和y,而是通过它们的吸气剂:即。 lat()lng()以避免将来版本出现同样的问题。希望这是导致你的方向无法渲染的问题。

获得lat和lng的正确推荐方法类似于以下内容:

results[0].geometry.location.lat().toFixed(3);
results[0].geometry.location.lng().toFixed(3);

因此,例如以下这一行应该是:

step.start_location = new google.maps.LatLng(step.start_location.wa,step.start_location.ya);
step.end_location = new google.maps.LatLng(step.end_location.wa,step.end_location.ya);

要:

step.start_location = new google.maps.LatLng(step.start_location.lat(), step.start_location.lng());
step.end_location = new google.maps.LatLng(step.end_location.lat(), step.end_location.lng());

Google地图数据的存储在服务期限内。在进一步使用数据存储之前,您可能需要先查看以下限制:

 10.1.3 Restrictions against Data Export or Copying.

    (a) No Unauthorized Copying, Modification, Creation of Derivative
     

工作或显示内容。您   不得复制,翻译,修改或   创造衍生作品(包括   创造或贡献一个   数据库),或公开显示任何   内容或其任何部分除外   明确允许这些   条款。例如,以下是   禁止:(i)创建服务器端   修改地图图块; (ⅱ)   拼接多个静态地图图像   一起显示一张地图   大于Maps API中允许的值   文件; (iii)创建邮件   基于的列表或电话营销列表   内容;或(iv)出口,   写作或将内容保存到   第三方的基于位置的平台   或服务。

    (b) No Pre-Fetching, Caching, or Storage of Content. You must not
     

预取,缓存或存储任何内容   内容,除了您可以存储:   (i)有限的内容   改善表现的目的   您的Maps API实施   暂时,安全,并在   不允许使用的方式   服务范围之外的内容;和   (ii)任何内容标识符或密钥   Maps API文档   特别允许你存储。对于   例如,您不得使用内容   创建一个独立的数据库   “场所”。

    (c) No Mass Downloads or Bulk Feeds of Content. You must not use the
     

以给您或您的方式提供服务   任何其他人获得弥撒   任何下载或批量Feed   内容,包括但不限于   数字纬度或经度   坐标,图像,可见地图   数据或放置数据(包括   商家信息)。例如,你   不允许提供批次   使用内容的地理编码服务   包含在Maps API中。

答案 1 :(得分:1)

我无法获得上述代码,所以我自己编写了代码。以下两个函数将序列化和反序列化DirectionsResult对象。但是,它只会序列化绘制路径所需的最小数据量。如果您发现返回的反序列化DirectionsResult缺少您需要的功能,则必须修改代码以添加您需要的任何其他DirectionsResult object attributes

请不要滥用此代码。 Google只允许您在特定情况下存储地图数据,并且只能暂时存储(即永远不会超过30 calendar days)。

//Takes Google Maps API v3 directionsRequest and directionsResult objects as input.
//Returns serialized directionsResult string.
function serializeDirectionsResult (directionsRequest, directionsResult) {
        var copyright = directionsResult.routes[0].copyrights;
        var travelMode = directionsRequest.travelMode;
        var startLat = directionsResult.routes[0].legs[0].start_location.lat();
        var startLng = directionsResult.routes[0].legs[0].start_location.lng();
        var endLat = directionsResult.routes[0].legs[0].end_location.lat();
        var endLng = directionsResult.routes[0].legs[0].end_location.lng();
        var steps = [];
        for (var i = 0; i < directionsResult.routes[0].legs[0].steps.length; i++){
                var pathLatLngs = [];
                for (var c = 0; c < directionsResult.routes[0].legs[0].steps[i].path.length; c++){
                        var lat = directionsResult.routes[0].legs[0].steps[i].path[c].lat();
                        var lng = directionsResult.routes[0].legs[0].steps[i].path[c].lng();
                        pathLatLngs.push( { "lat":lat , "lng":lng }  );
                }
                steps.push( pathLatLngs );
        }
        var serialSteps = JSON.stringify(steps);
        //Return custom serialized directions result object.
        return copyright + "`" + travelMode + "`" + startLat + "`" + startLng + "`" + endLat + "`" + endLng + "`" + serialSteps;
}

//Takes serialized directionResult object string as input.
//Returns directionResult object.
function deserializeDirectionsResult (serializedResult) {
        var serialArray = serializedResult.split("`");
        const travMode = serialArray[1];
        var directionsRequest = {
            travelMode: travMode,
            origin: new google.maps.LatLng(serialArray[2], serialArray[3]),
            destination: new google.maps.LatLng(serialArray[4], serialArray[5]),
        };
        var directionsResult = {};
        directionsResult.request = directionsRequest;
        directionsResult.routes = [];
        directionsResult.routes[0] = {};
        directionsResult.routes[0].copyrights = serialArray[0];
        directionsResult.routes[0].legs = [];
        directionsResult.routes[0].legs[0] = {};
        directionsResult.routes[0].legs[0].start_location = directionsRequest.origin;
        directionsResult.routes[0].legs[0].end_location = directionsRequest.destination;
        directionsResult.routes[0].legs[0].steps = [];
        var deserializedSteps = JSON.parse(serialArray[6]);
        for (var i = 0; i < deserializedSteps.length; i++){
                var dirStep = {};
                dirStep.path = [];
                for (var c = 0; c < deserializedSteps[i].length; c++){
                        var lat = deserializedSteps[i][c].lat;
                        var lng = deserializedSteps[i][c].lng;
                        var theLatLng = new google.maps.LatLng(lat, lng);
                        dirStep.path.push( theLatLng );
                }
                dirStep.travel_mode = travMode;
                directionsResult.routes[0].legs[0].steps.push( dirStep );
        }
        return directionsResult;
}

答案 2 :(得分:0)

对于仍然希望解决此问题的任何人,您实际上只需要将Lat / Lng属性转换为google.maps.LatLng对象。

function deserializeDirectionsResult(directions) {
    directions.routes.forEach(function (route) {
        route.legs.forEach(function (leg) {
            leg.end_location = new google.maps.LatLng(leg.end_location.lat, leg.end_location.lng)
            leg.start_location = new google.maps.LatLng(leg.start_location.lat, leg.start_location.lng)

            leg.steps.forEach(function (step) {
                step.end_location = new google.maps.LatLng(step.end_location.lat, step.end_location.lng);
                step.end_point = new google.maps.LatLng(step.end_point.lat, step.end_point.lng);
                step.start_location = new google.maps.LatLng(step.start_location.lat, step.start_location.lng);
                step.start_point = new google.maps.LatLng(step.start_point.lat, step.start_point.lng);

                step.lat_lngs.forEach(function (lat_lng) {
                    lat_lng = new google.maps.LatLng(lat_lng.lat, lat_lng.lng);
                });

                // Optional property
                if (step.hasOwnProperty('steps')) { 
                    step.steps.forEach(function (stepStep) {
                        stepStep.end_location = new google.maps.LatLng(stepStep.end_location.lat, stepStep.end_location.lng);
                        stepStep.start_location = new google.maps.LatLng(stepStep.start_location.lat, stepStep.start_location.lng);

                        stepStep.lat_lngs.forEach(function (lat_lng) {
                            lat_lng = new google.maps.LatLng(lat_lng.lat, lat_lng.lng);
                        });

                        stepStep.path.forEach(function (path_item) {
                            path_item = new google.maps.LatLng(stepStep.path.lat, stepStep.path.lng);
                        });
                    });
                }
            });
        });
    });

    return directions;   
}

答案 3 :(得分:0)

你也可以试试 lodash 的 _.cloneDeepWith:

function deserializeAnything(previouslyStringified) {
    return _.cloneDeepWith(previouslyStringified, function (value) {
        if (value.lat !== undefined && value.lng !== undefined) {
            return new google.maps.LatLng(value.lat, value.lng);
        }
    });
}

这基本上将每个 LatLngLiteral 转换为原始对象(或数组)内任何级别的 LatLng