openlayers 和 turf 网格应用

openlayers 和 turf 网格应用

在这里插入图片描述

<template>
    <div class="main">
        <div class="map" id="map"></div>
    </div>
</template>

<script lang="ts">
import {Component, Vue} from "vue-property-decorator"
import * as turf from '@turf/turf'
import 'ol/ol.css'
import {Feature, Map, Overlay, View} from 'ol'
import OSM from 'ol/source/OSM'
import {Tile, Vector} from 'ol/layer'
import {Zoom, Rotate, Attribution, Control, defaults, FullScreen, ScaleLine} from 'ol/control'
import {DragRotate, DragRotateAndZoom, defaults as defaultInteractions} from "ol/interaction";
import {toStringXY} from "ol/coordinate";
import {ImageCanvas, ImageStatic, TileDebug, TileImage} from "ol/source";
import ImageLayer from "ol/layer/Image";
import Projection from "ol/proj/Projection";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import {LineString, Point} from "ol/geom";
import {Circle, Fill, Icon, Stroke, Style} from "ol/style";
import {GeoJSON} from "ol/format";
import TileGrid from "ol/tilegrid/TileGrid";
import {transform} from "ol/proj";
import CircleStyle from "ol/style/Circle";
import {getVectorContext} from "ol/render";

@Component({})
export default class Ol extends Vue {
    map: any = null;
    markers: Array<any> = [];

    mounted() {
        this.initMarkers()
        this.$nextTick(() => {
            this.initMap()
        })
    }

    initMap() {
        let resolutions = [];
        for (let i = 0; i < 19; i++) {
            resolutions[i] = (Math.pow(2, 18 - i))
        }
        let projection = new ol.proj.get('EPSG:3857');
        let projectionExtent = projection.getExtent();

        let imgSource = new TileImage({
            //指定切片所用的坐标系
            //EPSG:4326 国际标准(地理坐标)
            //EPSG:3857 球体墨卡托(投影坐标)
            projection: projection,
            tileGrid: new TileGrid({
                // origin: ol.extent.getBottomLeft(projectionExtent),
                origin: [0, 0],
                //ol.proj.get('EPSG: 3857').getExtent()投影坐标系范围
                // origin: ol.extent.getBottomLeft(ol.proj.get('EPSG:3857').getExtent()),
                //自定义分辨率数组
                resolutions: resolutions,
                extent: projectionExtent,
                tileSize: [256, 256]
            }),
            tileUrlFunction: (tileCoord: any, pixelRatio: any, proj: any) => {
                if (!tileCoord) {
                    return ""
                }
                let z = tileCoord[0];//缩放级别
                let x = tileCoord[1];//x索引
                let y = tileCoord[2];//y索引
                x = x < 0 ? "M" + (-x) : x;
                y = y < 0 ? -y : "M" + y;
                return "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x=" + x + "&y=" + y + "&z=" + z + "&styles=pl&udt=20210730&scaler=1&p=1";
            }
        })
        this.map = new Map({
            target: 'map',
            interactions: defaultInteractions().extend([
                new DragRotateAndZoom()
            ]),
            controls: defaults().extend([
                new FullScreen(),
                new Rotate(),
                new ScaleLine(),
            ]),
            layers: [
                new Tile({
                    source: imgSource
                }),
                new Tile({
                    source: new TileDebug({
                        projection: projection,
                        tileGrid: imgSource.getTileGrid()
                    })
                }),
                new VectorLayer({
                    source: new VectorSource({
                        features: this.markers
                    }),
                    zIndex: 2,
                })
            ],
            view: new View({
                center: ol.proj.transform([104.06, 20], "EPSG:4326", "EPSG:3857"),
                zoom: 5,
                resolutions: resolutions
            })
        });

        this.map.on('click', (e: any) => {
            console.log(e.coordinate)
        })
        this.initGrid();
    }

    //初始化点位
    initMarkers() {
        let coordinates = [[104, 30], [104, 20], [105, 25], [101, 25]]
        this.markers = coordinates.map((item: any, index: number) => {
            let point = new Feature(new Point(ol.proj.transform(item, "EPSG:4326", "EPSG:3857")));
            point.setId(index);
            point.setStyle(new Style({
                image: new Icon({
                    anchor: [0.1, 0.1],
                    src: require('@/assets/login/sys.png')
                })
            }))
            return point;
        })
    }

    //初始化网格
    initGrid() {
        //extent: [minX, minY, maxX, maxY] 左下角 -》 右上角
        let bbox: any = [10663983.31137481, 2059417.837748297 ,12188497.832018718, 3566205.4453614634];
        let cellSide = 500;
        let options: any = {units: 'kilometers'};

        let squareGrid = turf.squareGrid(bbox, cellSide, options);
        // var point = turf.point(transform([114.2058, 33.2469], 'EPSG:4326','EPSG:3857'));
        let innerPolygon: any = [];
        let outPolygon:any = [];
        //遍历小网格
        turf.geomEach(squareGrid, (cur: any, index:any, properties:any,bbox:any)=>{
            // console.log(cur, properties)
            //筛选网格内的点位
            let count = this.markers.filter((e: any) =>{
                //判断点是否在小网格内
                return turf.booleanPointInPolygon(turf.point(e.values_.geometry.flatCoordinates),cur)
            })
            if(count.length > 0){
                innerPolygon.push(cur);
            }else{
                outPolygon.push(cur);
            }
        })

        let source1 = new VectorSource();
        source1.addFeatures(new GeoJSON().readFeatures(turf.featureCollection(outPolygon)));
        // source.addFeature(new GeoJSON().readFeature(point));
        let source2 = new VectorSource();
        source2.addFeatures(new GeoJSON().readFeatures(turf.featureCollection(innerPolygon)));

        this.map.addLayer(new VectorLayer({source: source1}))
        this.map.addLayer(new VectorLayer({
            source: source2,
            style: new Style({
                fill: new Fill({
                    color: '#00ff00'
                })
            })
        }))
    }
}
</script>

<style lang="scss" scoped>
.main {
    width: 100%;
    height: 100%;

    .map {
        width: 50%;
        height: 50%;
    }
}
</style>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值