如何将OpenLayers与Elm.Land集成?

huangapple go评论48阅读模式
英文:

How to integrate OpenLayers with Elm.Land

问题

我正在使用ElmLand的Web组件示例作为构建OpenLayers Web组件的指南,已经使用该网站的介绍创建了一个项目。

该应用程序在本地主机上运行,并有一个静默的控制台窗口。但页面上没有显示OpenLayers地图,只有之前的示例中的“Say, hello”按钮。

我已经在Home_.elmview中添加了一个node

view : Model -> View Msg
view model =
    { title = "Homepage"
    , body =
        [ Html.button [ Html.Events.onClick UserClickedButton ]
            [ Html.text "Say, hello" ]
        , Html.node "map" [] []
        ]
    }

我从node_modules/ol复制了ol.css到ElmLand的static目录中。
我的组件在ol-map.js中定义:

import '../../static/ol.css';
import OSM from 'ol/source/OSM';
import TileLayer from 'ol/layer/Tile';
import { Map, View } from 'ol';
import { fromLonLat } from 'ol/proj';

window.customElements.define('ol-map', class extends HTMLElement {
    connectedCallback() {
        const map = new Map({
            target: 'ol-map', // 也尝试过 target: this
            layers: [
                new TileLayer({
                    source: new OSM(),
                }),
            ],
            view: new View({
                center: fromLonLat([0, 0]),
                zoom: 2,
            }),
        });
        setTimeout(function () {
            console.log("map initializing: ", map, map.isRendered())
        }, 5000)
    }
})

Main.css

@import './ol.css';

body {
    padding: 32px;
    height: 100%;
}

#ol-map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
}

并且:

我没有编辑interop.js,自从添加了之前示例的OPEN_WINDOW_DIALOG代码以来。

浏览器的网络面板报告所有下载的文件状态为200,包括ol-map.jsol.cssol_source_OSM.jsol_layer_Tile.jsol.jsol_proj.js和以chunk-*.js开头的各种名称。

我添加了一个console.log(见上面的代码),当我打开http://localhost:1234/页面时,它确实打印到控制台。

它的地图{}输出包括:

loaded_ : true
maxTilesLoading_ : 16
ol_uid : "5"
values_ : {layergroup: LayerGroup, target: 'ol-map', view: View}

isRendered()的输出为false。

一切看起来都正常。但是没有地图显示。
我尝试集成three.js,就像Elm Land的与JS示例一样,一切正常工作。

英文:

I'm using ElmLand's web component example as a guide to building a web component for OpenLayers having created a project using the site's introduction.

The app runs in localhost with a silent console window.
But no OpenLayers map is appearing on the page. Just the earlier example "Say, hello" Button.

I've added a node to the Home_.elm view:

view : Model -> View Msg
view model =
    { title = "Homepage"
    , body =
        [ Html.button [ Html.Events.onClick UserClickedButton ]
            [ Html.text "Say, hello" ]
        , Html.node "map" [] []
        ]
    }

I've copied ol.css from node_modules/ol into ElmLand's static directory.
My component is defined in ol-map.js:

import '../../static/ol.css'
import OSM from 'ol/source/OSM'
import TileLayer from 'ol/layer/Tile'
import { Map, View } from 'ol'
import { fromLonLat } from 'ol/proj'

window.customElements.define('ol-map', class extends HTMLElement {
    connectedCallback() {
        const map = new Map({
            target: 'ol-map', // also tried target: this
            layers: [
                new TileLayer({
                    source: new OSM(),
                }),
            ],
            view: new View({
                center: fromLonLat([0, 0]),
                zoom: 2,
            }),
        });
        setTimeout(function () {
            console.log("map initialising: ", map, map.isRendered())
        }, 5000)
    }
})

Main.css:

@import './ol.css';

body {
    padding: 32px;
    height: 100%;
}

#ol-map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
}

And:

I've not edited interop.js since adding the previous example's OPEN_WINDOW_DIALOG code.

Browser Network pane reports status 200 for all the files downloaded including ol-map.js, ol.css, ol_source_OSM.js, ol_layer_Tile.js, ol.js, ol_proj.js and various names beginning with chunk-*.js.

I added a console.log (see code, above) and it does print to the console when I open the page at http://localhost:1234/

It's output of map{} includes:

loaded_ : true
maxTilesLoading_ : 16
ol_uid : "5"
values_ : {layergroup: LayerGroup, target: 'ol-map', view: View}

and isRendered() outputs false.

It all looks in order. But no map is displayed.
I've tried integrating three.js as Elm Land's working with JS example and that worked fine.

答案1

得分: 2

Html.node中的字符串需要与customElements.define中的字符串匹配,才能识别出自定义元素。

你需要将Html.node ""map""改为Html.node ""ol-map""

另外,据我所知,target: 'map'这一行实际上应该是target: this,因为你不是在查找具有id="map"的元素,而是刚刚创建的自定义元素。

英文:

The string in Html.node needs to match the string in customElements.define for it to recognise the custom element.

You need to change Html.node "map" to Html.node "ol-map".

Also, AFAIK the target: 'map' line should really be target: this, as you are not looking up an element with the id="map", but rather the custom element you just created.

答案2

得分: 1

需要创建一个元素,附加到自定义元素上,以供OpenLayers代码进行定位:

import OSM from 'ol/source/OSM'
import TileLayer from 'ol/layer/Tile'
import { Map as MapElement, View } from 'ol'
import { fromLonLat } from 'ol/proj';

class OpenLayersElement extends HTMLElement {

    constructor() {
        super()
    }

    async connectedCallback() {
        // OpenLayers需要定位的元素
        const div = document.createElement('div')
        div.id = 'map'
        this.appendChild(div)

        // 在自定义元素内创建一个OpenLayers地图
        const map = new MapElement({
            target: 'map',
            layers: [
                new TileLayer({
                    source: new OSM(),
                }),
            ],
            view: new View({
                center: fromLonLat([0, 0]),
                zoom: 2,
            }),
        });
    }
}

window.customElements.define('ol-map', OpenLayersElement)
英文:

One needs to create an element, attached to the custom element for the OpenLayers code to target:

import OSM from 'ol/source/OSM'
import TileLayer from 'ol/layer/Tile'
import { Map as MapElement, View } from 'ol'
import { fromLonLat } from 'ol/proj'


class OpenLayersElement extends HTMLElement {

    constructor() {
        super()
    }

    async connectedCallback() {
        // element required for OpenLayers to target
        const div = document.createElement('div')
        div.id = 'map'
        this.appendChild(div)

        // Create an OpenLayers map inside the custom element
        const map = new MapElement({
            target: 'map',
            layers: [
                new TileLayer({
                    source: new OSM(),
                }),
            ],
            view: new View({
                center: fromLonLat([0, 0]),
                zoom: 2,
            }),
        });
    }
}

window.customElements.define('ol-map', OpenLayersElement)

huangapple
  • 本文由 发表于 2023年8月10日 20:22:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76875701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定