angular中使用leaflet与scss的一些问题。

这次以前做的一个项目又双叒叕加辣新需求

自然而然又有了新问题



首先如下图所示,需要两个地图

angular中使用leaflet与scss的一些问题。_第1张图片

左侧的是子组件中的地图,右侧的是父组件中的地图,子组件中传入了父组件的this对象。

在子组件中的ngOnInit生命周期钩子中初始化地图的话会出现
image.png
或者地图已经被初始化过的错误,所以放在ngAfterViewInit中初始化就没有问题了

然后遇到的第一个问题就是,地图显示不全,如下图所示
angular中使用leaflet与scss的一些问题。_第2张图片

可以看到地图只显示很小的一片区域,移动的时候也不会扩大显示区域。这时候一般在正确的地方写上代码this.map.invalidateSize(true)就行了,官方文档里对这个方法的描述是
image.png
简而言之就是根据容器大小动态更新地图。 之所以说一般情况下这样写就对了,因为还有其他的情况

第二种情况也会导致地图显示不全
就是img的样式问题,如下图
angular中使用leaflet与scss的一些问题。_第3张图片
这里在父组件中定义了map的预设样式。

子组件中也同样,应用到了这个样式,我更改了leaflet中的mark,标记用的不是点,用的是img图片代替,我在样式中使用了样式穿透
:host ::ng-deep .divlayer .divcontent img 就会造成上面的地图显示不全。 解决办法就是更具体到img中为图标的那一类
也就是:host ::ng-deep .divlayer .divcontent img.leaflet-marker-icon 这样问题就解决了,皆大欢喜

scss和less在angular中使用的不同目前发现的一点就是

less中可以使用:host /deep/ xxx{}不会报错,而在scss中/deep/会报错,可以用::ng-deep替代。

    • -

2021-02-22更新

angular中使用leaflet与scss的一些问题。_第4张图片

如图,在leaflet中实现连线功能

下面开始讲如何实现

首先需要新建一个图层,画的线就画在这个图层上。

this.testLayerGroup = new L.layerGroup()//初始化图层
this.testLayerGroup.addTo(this.map)//添加图层到海图

上面两行代码需要写在ngOnInit生命周期中,并且要在地图创建完成以后

然后写一个方法 drawLine(){//划线}

方法中

drawLine(){
    let end:boolean=false;//用于控制划线方法结束与否

    this.testLayerGroup.clearLayers()//清除图层
    this.testCoordinates = []//清空数组

    let layerId: any = null;
    let layerId2: any = null;
    //这两个id稍后用到的时候再解释是干什么用的

    this.map.on('mousedown',(e:any)=>{//当鼠标按下的时候触发 e的内容如图1所示
        let coodinate:any = [e.latlng.lat,e.latlng.lng]//用来存放坐标点 第一个是纬度(latitude),第二个是经度(longitude)
        let exist:boolean:any = false;//用于判定是否为同一个点
        for (let i = 0; i < this.testCoordinates.length; i++) {//如果找到了已存在的点(通常为双击的时候)就标记为已点过,从而不会进入到画点的方法中
            if (this.testCoordinates[i][0] == e.latlng.lat && this.testCoordinates[i][1] == e.latlng.lng) {
              exist = true;
              break;
            }
        }
        if(!exist){//如果非同样的点
            let startpoint = L.circleMarker(coodinate,{//点击的点位做成圆形标记比较好认
                radius:2 //这个是圆点的半径,还有其他很多的属性,在leaflet官网里面有详细的描述
            })
            this.testLayerGroup.addLayer(startpoint);//把起始点放进图层里
            this.testCoordinates.push([e.latlng.lat,e.latlng.lng]);//把点位加入到数组集合里
            let len:number = this.testCoordinates.length;
            if(len>=2){//有两个点的时候,增加距离文字提示
                let coordinate1:any = this.testCoordinates[len-2]//上一个点
                let coordinate2:any = this.testCoordinates[len-1]//这个点
                let line1 = L.polyline([coordinate1,coordinate2],{//画线需要两个点
                    weight:2 //线的粗细程度 其他属性官网由
                }).setText('▶',{ repeat: false, center: true, offset: [4, 4], attributes: { fill: 'red' } })//setText官网上没有相关的描述但是具体的作用是在线的中间添加文字性的描述,示例图中没有改变颜色,所以代码里是红色的,但是图里是黑色的。
                this.testLayerGroup.addLayer(line1)//把这个线加入到图层里
                let distance:any = (L.latLng(coordinate1).distanceTo(L.latLng(coordinate2))/1852).toFixed(2);//计算距离,海里是米除以1852,结果保留两位小数
                let tips = L.divIcon({//距离提示框的相关属性
                    html:`

${distance}海里`, iconSize:[100,30], className:'divIcon'//类名 所以可以在上面的hmtl写上样式,也可以在样式文件中通过类名改变样式 }) let mark1:any = L.marker(coordinate2,{icon:tips});//把距离提示作为一个标记 this.testLayerGroup.addLayer(mark1);//把标记插入到图层中 } this.map.on('mousemove',(e1:any)=>{//当鼠标移动的时候 if(!end){//非结束的时候 if (layerId != null) {这个id有的话 this.testLayerGroup.removeLayer(layerId);//清除掉这个id的图层 layerId = null;//id设为空 } if (layerId2 != null) {//同上操作 this.testLayerGroup.removeLayer(layerId2); layerId2 = null; } let coordinate2:any = [e1.latlng.lat,e1.latlng.lng];//最新的点位 let coordinate1:any = this.testCoordinates[len-1];//数组中最后一个点位 //这两个点位就是移动的时候划线用的,同时上面的id是为了时刻保持只有一条线起作用的,不然的话就会如图2一样 //下面的代码上面已经重复过了 let distance: number = Number((L.latLng(coordinate1).distanceTo(L.latLng(coordinate2)) / 1852).toFixed(2)); if (distance != 0) { let line = L.polyline([coordinate1, coordinate2], { weight: 2 }).setText('▶', { repeat: false, center: true, offset: [4, 4] }); this.testLayerGroup.addLayer(line) layerId = this.testLayerGroup.getLayerId(line);//线的id设立一下 let tips = L.divIcon({ html: `

${distance}海里`, iconSize: [100, 30], className: 'divIcon' }) let mark1: any = L.marker(coordinate2, { icon: tips }); this.testLayerGroup.addLayer(mark1); layerId2 = this.testLayerGroup.getLayerId(mark1);//点的id设立一下 } } }) } }) this.map.on('dblclick',()=>{//双击以后的事件 let len:number = this.testCoordinates.length; if(len>1){//数组长度大于1的时候 this.map.off('mousedown');//结束点击事件 this.map.off('dblclick');//结束双击事件 end = true//划线方法状态改为结束 } let distance:number = 0; for(let i = 1;i {//防止点到其他地方然后把这个总里程弹窗覆盖掉 layer.bindPopup(popup); }); popup.openOn(this.map); }) }

angular中使用leaflet与scss的一些问题。_第5张图片
图1

angular中使用leaflet与scss的一些问题。_第6张图片
图2

这样就完成了一个划线的方法,具体的触发可以搞一个按钮,点一下就执行draw方法。


2021-3-10 17:05

li{
    transition:0.3s;
}
li:hover{
    left:0.4em;
}

样式中使用transition
hover的时候无法产生动效的原因其实很简单
就是在li中加上left:0px就行

li{
    left:0px;
    transition:0.4s
}

你可能感兴趣的:(angular中使用leaflet与scss的一些问题。)