异步加载诺基亚地图Javascript API

9

我正试图异步加载Nokia Maps 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://dev59.com/Emsz5IYBdhLWcg3wn5fa#7884407)。

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

new nokia.maps.map.Display();

有没有办法做到这一点,或者有人曾经成功地做到了?我可能漏掉了什么。
编辑:实际上,我正在尝试在页面上异步地编写脚本,而不是异步创建地图(当然这不是问题)。
谢谢。
2个回答

8

HERE Maps API for JavaScript (3.0)

新版的3.0 HERE 地图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(或覆盖)保存在头部,或者使用require-css等requirejs插件加载它。应该注意,在配置中需要添加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及以上)支持异步加载,如下所示

详细信息可以在Feature.load方法和API Reference中找到 Feature.load有两个回调函数,一个是成功的(您可以继续添加App ID和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 参考文档已经移动到此处 - Veksi
1
@Veski - 我已经更新了答案,澄清了新的 3.x 版本在异步加载方面要容易得多。我不鼓励在新项目中继续使用已弃用的 2.x 版本。 - Jason Fox
事实上,现在开始使用3.n API可能是明智的选择。虽然我认为在这里也有2.n的做法会很有帮助,因为Here和GitHub上几乎所有的示例都是关于2.n API的。而且至少我对3.n版本的使用还有些困难,所以在目前来看,2.n可能是更合适的选择(对于我的业余项目)。 - Veksi
我正在使用 JSP 和 Struts,我是否只需要在我的 JavaScript 文件中包含所需的函数和在我的 JSP 文件中包含 requirejs.config 文件?还是我需要下载 RequireJS 或将其作为脚本添加到我的 JSP 文件中? - 3rdeye7
你应该像 https://github.com/volojs/create-template 这样的结构为目标 - 正如你所看到的,requirejs库在渲染文件的<head>标签中以<script>标签的形式被加载。 - Jason Fox
显示剩余3条评论

2

你应该看一下 jHERE 库,如果想要使用 Nokia 地图 API 并具有流畅的异步加载和其他酷炫功能。


你好,我正在使用MH5开发一个应用程序,以在iOS和Android中集成诺基亚地图。我想要一个可拖动的标记,那么这在MH5中是否可能或者通过jHERE插件实现呢? - user869123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接