【问题标题】:Asynchronously loading Nokia Maps Javascript API异步加载诺基亚地图 Javascript API
【发布时间】:2014-12-10 06:21:44
【问题描述】:

我正在尝试异步加载诺基亚地图 JavaScript API:

var oScript  = document.createElement('script');
oScript.type = 'text/javascript';
oScript.async = true;
oScript.src  = "http://api.maps.nokia.com/2.2.3/jsl.js?with=maps,positioning,placesdata";
document.body.appendChild(oScript);

正如预期的那样,它不能立即工作,所以我尝试覆盖 document.write 认为这可能是问题,但无济于事(例如,我这样做了https://stackoverflow.com/a/7884407/1741150)。

我遇到的错误是 nokia.maps.map 基本上没有定义(因此,我无法使用以下方法创建地图:

new nokia.maps.map.Display();

有没有办法做到这一点,或者有人曾经设法做到这一点?我可能遗漏了什么

编辑:我实际上是在尝试在页面中异步编写脚本,而不是异步创建地图(这当然不是问题)

谢谢,

【问题讨论】:

    标签: javascript here-api


    【解决方案1】:

    HERE Maps API for JavaScript (3.0)

    较新的 3.0 HERE Maps API for JavaScript 非常模块化,并且完全支持异步加载。例如,可以使用requirejs 来加载一个简单的地图,如下所示:

      require(['mapsjsService','mapsjsEvents', 'mapsjsUi'], function () {
    
          var platform = new H.service.Platform({
              app_id: '<YOUR APP ID>',
              app_code: '<YOUR TOKEN>'
          });
          var defaultLayers = platform.createDefaultLayers();
          var map = new H.Map(document.getElementById('map'),
            defaultLayers.normal.map);
          var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
          var ui = H.ui.UI.createDefault(map, defaultLayers);
        });
    

    配置文件需要分配如下:

     requirejs.config({
        baseUrl: '.',
        waitSeconds: 0,
        map: {
          '*': {
            'css': 'require-css' // or whatever the path to require-css is
          }
        },
        paths: {
            'mapsjsCore' : 'https://js.api.here.com/v3/3.0/mapsjs-core',
            'mapsjsService' : 'https://js.api.here.com/v3/3.0/mapsjs-service',
            'mapsjsEvents' : 'https://js.api.here.com/v3/3.0/mapsjs-mapevents',
            'mapsjsUi' :'https://js.api.here.com/v3/3.0/mapsjs-ui',
    
            'mapsjsCss' :'https://js.api.here.com/v3/3.0/mapsjs-ui',
          },
          shim: {
            'mapsjsService': {
              deps: ['mapsjsCore']
            },
            'mapsjsEvents': {
              deps: ['mapsjsCore']
            },
            'mapsjsUi': {
              deps: ['mapsjsCore', 'css!mapsjsCss']
            }
          }
        });
    

    可以看出,所有模块都依赖mapsjsCore,但没有一个子模块相互依赖。 mapsjsUi 是一种特殊情况,因为它具有用于默认外观的关联 CSS 文件。您可以在标题中保留默认 CSS(或您的覆盖),或者使用 requirejs 插件(例如 require-css)加载它。需要注意的是,配置中需要 waitSeconds:0 行,以避免在第一次将 HERE Maps for JavaScript 库下载到浏览器时超时,因为它们不会在本地找到,所以您至少依赖一次互联网连接的速度。

    或者使用 Jquery:

    $.getScript('https://js.api.here.com/v3/3.0/mapsjs-core.js', function() {
      $.getScript('https://js.api.here.com/v3/3.0/mapsjs-service.js', function() {
        $.getScript('https://js.api.here.com/v3/3.0/mapsjs-mapevents.js', function() {
          $.getScript('https://js.api.here.com/v3/3.0/mapsjs-mapevents.js', function() {
            ////
            //
            // Don't forget to set your API credentials
            //
            var platform = new H.service.Platform({
              app_id: 'DemoAppId01082013GAL',
              app_code: 'AJKnXv84fjrb0KIHawS0Tg',
              useCIT: true
            });
            //
            //
            /////
            var defaultLayers = platform.createDefaultLayers();
            var map = new H.Map(document.getElementById('map'),
              defaultLayers.normal.map, {
                center: {
                  lat: 50,
                  lng: 5
                },
                zoom: 4
              });
            var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
            var ui = H.ui.UI.createDefault(map, defaultLayers);
          });
        });
      });
    });
    body {
           margin: 0;
           padding: 0;
         }
    
         #map {
           width: 100%;
           height: 100%;
           position: absolute;
           overflow: hidden;
           top: 0;
           left: 0;
         }
    <head>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      <link rel="stylesheet" type="text/css"
        href="http://js.api.here.com/v3/3.0/mapsjs-ui.css" />
    </head>
    <body>
    <div id="map"></div>
    </body>
    
     

    Nokia Maps API for JavaScript (2.2.4-2.5.4)

    Nokia Maps API for JavaScript(2.2.4 及更高版本)的最近弃用版本支持如下所示的异步加载

    详情可参考API ReferenceFeature.load方法 Feature.load 有两个回调,一个代表成功(您可以在其中继续添加App ID and token,显示地图等,一个代表失败。

    // this is our initial script that will load jsl.js
    var oScript = document.createElement("script"),
      //once the jsl.js is load, we load all features
      onScriptLoad = function() {
        nokia.Features.load(
          // here we get all features (provide one or many "with" parameters
          nokia.Features.getFeaturesFromMatrix(["all"]),
          // an callback when everything was successfully loaded
          onApiFeaturesLoaded,
          // an error callback
          onApiFeaturesError,
          // a target document (or null if the current document applies)
          null,
          // a flag indicating that loading should be asynchronous
          false
        );
      },
      // once all features we loaded, we can instantiate the map
      onApiFeaturesLoaded = function() {
    
        /////////////////////////////////////////////////////////////////////////////////////
        // Don't forget to set your API credentials
        //
        // Replace with your appId and token which you can obtain when you 
        // register on http://api.developer.nokia.com/ 
        //
        nokia.Settings.set("appId", "YOUR APP ID");
        nokia.Settings.set("authenticationToken", "YOUR TOKEN");
        //          
        /////////////////////////////////////////////////////////////////////////////////////
    
        var mapContainer = document.getElementById("mapContainer");
        var map = new nokia.maps.map.Display(mapContainer, {
          center: [40.7127, -74.0059],
          zoomLevel: 13,
          components: [new nokia.maps.map.component.ZoomBar(),
            new nokia.maps.map.component.Behavior(),
          ]
        });
      },
      // if an error occurs during the feature loading
      onApiFeaturesError = function(error) {
        alert("Whoops! " + error);
      };
    
    oScript.type = "text/javascript";
    // NOTE: tell jsl.js not to load anything by itself by setting "blank=true"
    oScript.src = "http://api.maps.nokia.com/2.2.4/jsl.js?blank=true";
    // assign the onload handler
    oScript.onload = onScriptLoad;
    
    //finally append the script
    document.getElementsByTagName("head")[0].appendChild(oScript);
         body {
           margin: 0;
           padding: 0;
         }
    
         #mapContainer {
           width: 100%;
           height: 100%;
           position: absolute;
           overflow: hidden;
           top: 0;
           left: 0;
         }
    <!DOCTYPE html>
        <html>
            <head>
                <meta http-equiv="content-type" content="text/html; charset=utf-8">
                <title>Asynchronous Loading</title>
            </head>
            <body>
                <div id="mapContainer"></div>
    
           </body>
        </html>

    【讨论】:

    • 请注意,Feature.load 的 API 参考显然已移至 here
    • 另外值得注意的是,自第 3 版开始以来,加载功能发生了变化。更多信息请访问developer.here.com/documentation/versions
    • @Veski - 我更新了答案以澄清新的 3.x 版本更容易异步加载。我不鼓励在新项目中继续使用已弃用的 2.x
    • 确实,现在开始使用 3.n API 可能是谨慎的做法。尽管我认为在这里使用 2.n 做事方式也会有所帮助,因为 Here 和 GitHub 上的几乎所有示例都是关于 2.n API 的。至少我在 3.n 版本上挣扎得够多了,目前,2.n 可能是一个更合适的选择(对于我的爱好项目)。
    • Feature.load 链接提供 HTTP 404。
    【解决方案2】:

    如果您想使用诺基亚地图 API,您应该看看 jHERE 库,它可以为您提供流畅的异步加载以及一系列很酷的其他功能。

    【讨论】:

    • 您好,我正在开发一款使用 MH5 的应用程序,用于在 iOS 和 Android 中集成诺基亚地图。我想要一个可拖动的标记,所以可以在 mh5 或 jHERE 插件中使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多