【问题标题】:Carto v4 + StoryMap - How to link Carto layer marker data to StoryMap scenesCarto v4 + StoryMap - 如何将 Carto 图层标记数据链接到 StoryMap 场景
【发布时间】:2021-03-10 04:07:43
【问题描述】:

我一直在开发与 Carto.js v4 配合使用的 StoryMap 可视化(根据:https://github.com/jakobzhao/storymap/ 和特别是本示例:https://bl.ocks.org/oriolbx/c2bd7fd47ffd448909daec58f88c28ae)。我已经能够设置标记弹出窗口以及其他一些很酷的东西,比如它们之间的线条和俯冲箭头。不幸的是,当我尝试将这些标记放在不同的场景中时,我一直无法成功添加代码。

在下面的代码中,我设置了一个类似“const cartLayer = new carto...”的 Carto 层,并将其添加到层定义中(层:client.getLeafletLayer),然后在 StoryMap 部分中添加了对它的引用(layers.cartoLayer.layer.addTo(map2).

这适用于我放置在任何场景中的名为 cartoLayer 的图层。但是,当我想取出 cartoLayer 并使用“LisgooldLayer”Carto 图层在“Lisgoold”场景中使用特定标记时,然后是 StoryMap 部分无法识别图层定义。我检查了 Carto.js 文档,但找不到定义图层的方法,以便 StoryMap 可以引用它。我可以让“layer4”显示没有问题,但不是 lisgooldLayer,其他示例项目中的大多数其他层定义都使用 GEOJson。

此代码中是否有我遗漏的内容?

提前致谢。

     // set CARTO client
       const client = new carto.Client({
         apiKey: '{CARTO-KEY}',
         username: '{CARTO-USER}'
       });
       const source = new carto.source.SQL('
           SELECT * FROM CARTOSOURCE
       ');
       const sourceLisgoold = new carto.source.SQL('
           SELECT * FROM CARTOSOURCE
           WHERE scene='Lisgoold'
       ');
       // define CartoCSS code to style data on map
       const style = new carto.style.CartoCSS('
         #layer{
             marker-fill: #336699;
             marker-allow-overlap: false;
         }
         #layer
           #layer[scene = "overview"]{
               marker-fill: #fbb4ae;
               marker-allow-overlap: false;
           }
           #layer[scene = "Lisgoold"]{
             marker-width: 20;
               marker-fill: #fbb4ae;
               marker-allow-overlap: false;
           }
           #layer[scene = "Salesman"]{
               marker-fill: #b3cde3;
               marker-allow-overlap: false;
           }
           #layer[scene = "England"]{
               marker-fill: #ccebc5;
               marker-allow-overlap: false;
           }
           #layer[scene = "SalesmanReturn"]{
               marker-fill: #333333;
               marker-allow-overlap: false;
           }
           #layer[scene = "USJourney"]{
               marker-fill: #ffffff;
               marker-allow-overlap: false;
           }
           #layer[scene = "WorkCanada"]{
               marker-fill: #336699;
               marker-allow-overlap: false;
           }
           #layer[scene = "LifeInChicago"]{
               marker-fill: #ff0000;
               marker-allow-overlap: false;
           }
           #layer[scene = "WorkUS"]{
               marker-fill: #fbfbfb;
               marker-allow-overlap: false;
           }
           #layer[scene = "TravelToUs"]{
               marker-fill: #fafafa;
               marker-allow-overlap: false;
           }
           #layer[scene = "FamilyTragedy"]{
               marker-fill: #ccc333;
               marker-allow-overlap: false;
           }

       ');
// create CARTO layer from source and style variables
const cartoLayer = new carto.layer.Layer(source, style, {
 featureOverColumns: (['scene', 'location_address','landmark_not_on_gis'])
});
const lisgooldLayer = new carto.layer.Layer(sourceLisgoold, style, {
 featureOverColumns: (['scene', 'location_address','landmark_not_on_gis'])
});
// add CARTO layer to the client
client.addLayers([cartoLayer, lisgooldLayer]);
// define layers that will be used on the map
var layers = {
           basemap: {
               layer: L.tileLayer('https://cartocdn_{s}.global.ssl.fastly.net/base-antique/{z}/{x}/{y}.png')
           },
           cartoLayer: {
               layer: client.getLeafletLayer()
           },
           lisgooldLayer: {
              layer:  lisgooldLayer
           },
           layer4: {  //https://github.com/wbkd/leaflet-swoopy
            layer: L.swoopyArrow([53.4120954,-3.056141], [56.9900112,-31.7339369], {
              text: 'All aboard for Quebec!',
              weight: 10,
              opacity: 0.2,
              fontSize: 20,
              factor: -0.9,
              color: "#bb0017",
              iconAnchor: [0, 0],
              iconSize: [200,150],
              textClassName: "arrow-label"
          })
          },
           layer5: {  //https://github.com/wbkd/leaflet-swoopy
           layer: L.swoopyArrow([54.5945837, -32.0337078], [54.5945837, -39.0337078], {
              text: 'worlds',
              weight: 2,
              opacity: 0.7,
              fontSize: 20,
              color: "#ffea00",
              iconAnchor: [0, 0]
          })
          },
};
// define scenes
let scenes = {
           overview: { lat: 51.9735556, lng: -152255582, zoom: 4, layers: [], name: "Home" },
           Home: { lat: 51.9735556, lng: -152255582, zoom: 4, layers: ['basemap','cartoLayer'], name: "Home" },
           Lisgoold: { lat: 51.9735556, lng: -8.2255582, zoom: 10, layers: ['basemap','lisgooldLayer'], name: "Lisgoold" },
           Salesman: { lat: 52.484837, lng: -8.2613306, zoom: 7, layers: ['basemap','cartoLayer'], name: "Salesman" },
           England: { lat: 52.5945837, lng:-2.0337078,  zoom: 9, layers: ['basemap','cartoLayer'], name: "England" },
           SalesmanReturn: {lat: 51.9735556, lng: -8.2255582,  zoom: 10, layers: ['basemap','cartoLayer'], name: "SalesmanReturn" },
           USJourney: {lat: 52.5945837, lng:-30.0337078,  zoom: 5, layers: ['basemap','cartoLayer'], name: "USJourney" },
           WorkCanada: {lat: 48.7321991, lng:-79.7597816,  zoom: 4, layers: ['basemap','cartoLayer'], name: "WorkCanada" },
           TravelToUS: {lat: 47.0151458, lng:-94.7614612,  zoom: 6, layers: ['basemap','cartoLayer'], name: "TravelToUS" },
           WorkUS: {lat: 41.8333925, lng:-88.0121484,  zoom: 10, layers: ['basemap','cartoLayer'], name: "WorkUS" },
           Marriage: {lat: 41.8270076, lng:-87.6455073,  zoom: 14, layers: ['basemap','cartoLayer'], name: "Marriage" },
           LifeInChicago: {lat: 41.8333925, lng:-88.0121484,  zoom: 11, layers: ['basemap','cartoLayer'], name: "LifeInChicago" },
           FamilyTragedy: {lat: 41.9028448, lng:   -87.6857373,  zoom: 11, layers: ['basemap','cartoLayer'], name: "FamilyTragedy"},
           CrossingAtlantic: {lat: 52.5945837, lng:-30.0337078,  zoom: 5, layers: ['basemap','cartoLayer', 'layer4'], name: "CrossingAtlantic" },
           FamilyGraves: {lat: 41.8333925, lng:-88.0121484,  zoom: 11, layers: ['basemap','cartoLayer'], name: "FamilyGraves"},
           StillInChicago: {lat: 41.8333925, lng:-88.0121484,  zoom: 11, layers: ['basemap','cartoLayer'], name: "StillInChicago"}
};
// initializaze storymap
$('#storymap').storymap({
           scenes: scenes,
           layers: layers,
           baselayer: layers.basemap,
           legend: true,
           loader: true,
           flyto: false,
           credits: "Built with Carto, StoryMap and Leaflet, 2021",
           scalebar: true,
           scrolldown: true,
           progressline: true,
           navwidget: true,
createMap: function () {
   let map2 = L.map($(".storymap-map")[0], { zoomControl: false }).setView([30, 0], 3);
   const popup = L.popup({closeButton: true});
cartoLayer.on('featureClicked', featureEvent => {
           var popup = L.popup()
           .setLatLng(featureEvent.latLng)
           let content = '';
             if (featureEvent.data.scene) {
                content += '<p>';
                content += featureEvent.data.scene;
                content += '</p><p>';
                content += featureEvent.data.landmark_not_on_gis;
                content += '</p><p>';
                content += featureEvent.data.location_address;
              }
            var line = L.polyline([
              [51.9674951, -8.2364881],
              [52.2662119, -8.2786411],
              [52.3745288, -7.9340018],
              [52.6801578, -7.8111139],
              [52.8555496, -7.5954776],
              [52.9628186, -7.7504342],
              [52.9391769, -7.6398531],
              [52.9942281, -7.4757189],
              [53.0426599, -7.3258656],
              [53.1674088, -6.9202995],
              [53.1443264, -6.8470534],
              [53.1062715, -6.0733409],
              [53.3242381, -6.3857864],
              [53.3288689, -6.2392783],
              [53.2650105, -6.1237033],
              [53.1970187, -6.1308245],
              [52.9825088, -6.0602595],
              [52.7950711, -6.1748422],
              [52.8581642, -6.2179385],
              [52.8824992, -6.2431992],
              [52.6757346, -6.303057],
              [52.5058482, -6.5894459],
              [52.5031391, -6.5624348],
              [52.3945888, -6.9615096],
              [52.2474998, -7.1480493],
              [52.0914087, -7.6386446],
              [51.9534288, -7.8755096],
              [51.9674951, -8.2364881]
            ]);
 map2.addLayer(line);
 var animatedMarker = L.animatedMarker(line.getLatLngs());
 map2.addLayer(animatedMarker);
 // add values to Leafet popup element
 popup.setContent(content).openOn(map2);
});
 // add basemap
 this.baselayer.layer.addTo(map2);
 // add carto layer
 layers.cartoLayer.layer.addTo(map2);
 //layers.lisgooldLayer.layer.addTo(map2);
 return map2;
}
});

【问题讨论】:

    标签: javascript leaflet cartodb


    【解决方案1】:

    我认为您没有在 const where 上转义引号;

    const sourceLisgoold = new carto.source.SQL(' 从 CARTOSOURCE 中选择 * WHERE 场景='Lisgoold' ');

    【讨论】:

    • 谢谢你,@Trevr - 我用反斜杠尝试过,但我得到了这个错误(索引):226 Uncaught SyntaxError: Invalid or unexpected token ... 然后还有一个反引号字符,但这会生成StoryMap 稍后在代码中出现错误:(index):428 Uncaught TypeError: layers.lisgooldLayer.addTo is not a function
    • 除此之外,我一直在编辑最后的 StoryMap 部分以删除 layers.cartoLayer.layer.addTo(map2);并将其替换为:client.getLeafletLayer().addTo(map2);为了包含 lisgooldLayer,但它给出了响应:leaflet.js:5 Uncaught Error: The provided object is not a Layer So StoryMap 似乎没有添加图层,因为它不是图层类型。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多