图形系统开发实战课程:进阶篇(上)——10.应用实例:交通路网


[

图形开发学院|GraphAnyWhere

  • 课程名称:图形系统开发实战课程:进阶篇(上)
  • 课程章节:“图形样式”
  • 原文地址:https://www.graphanywhere.com/graph/advanced/2-10.html

第十章 应用实例:交通路网

\quad 在前面几章的讲解中,我们已经讲述了图形系统中的一些重要概念,以及图形平移缩放、拾取、视点控制等图形交互功能。本章通过一个实际应用案例,采用 anyGraph 实现对交通路网数据展示功能,同时复习和回顾之前几个章节讲述的一些技巧。

\quad 交通路网业务通常划分在地理信息系统的业务领域,由于本示例并不涉及到地理分析计算方面的功能,因此交通路网也可以划分在图形系统业务领域中。

1 数据分析

\quad 本实例中采用的交通路网样例数据包括了某科技园区约9万平方米的地理范围,其数据类型可分为:道路中心线、道路路面、道路中的虚线、道路中的实线、道路中方向箭头共5类数据。其WEB墨卡托坐标范围为:[12683000, 2574000, 12685600, 2577400]

\quad 上述这些数据均采用采用 GeoJSON 格式,GeoJSON 是一种对各种地理数据结构进行编码的格式,该格式采用Javascript对象表示法(JavaScript Object Notation, 简称JSON),是一种地理空间信息数据交换格式。GeoJSON对象 包含了几何、特征或者特征集合等信息。

1.1 道路中心线

\quad 道路中心线数据为线类型数据,描述了道路的走向,其几何信息较为简单,通常在仅需显示道路位置和走向的场景中使用道路中心线代替实际的道路路面数据。下图采用土黄色线条即为道路中心线,该线设置了一定的线宽使之看起来与道路相似:

在这里插入图片描述

\quad 道路中心线数据以 GeoJSON 格式存储在文件中,一个 GeoJSON 对象表示一条道路。该对象中不仅包含了道路中心线的坐标数据,还在特征属性中包含了道路名称信息,例如下面这个 GeoJSON 对象中, properties 属性中的 name 属性指的是 道路名称,features 属性中的 coordinates 属性指的是该道路的坐标。

\quad 此外,该GeoJSON对象中还包含了crs属性,表示该坐标的坐标参考系统,关于这部分的内容我们将在后续课程中讲解,在这里只需知道该道路采用了 WGS84 地理坐标系,在绘制图形的时候需要经过投影转换为平面坐标系。

\quad 道路中心线 GeoJSON 对象如下所示:

{
	"type": "FeatureCollection",
	"crs": {
		"type": "name",
		"properties": {
			"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
		}
	},
	"features": [
		{
			"type": "Feature",
			"id": "63-3250080",
			"properties": {
				"name": "海德三道"
			},
			"geometry": {
				"type": "LineString",
				"coordinates": [
				    [113.9358854, 22.5218712],
				    [113.9358857, 22.5218712],
				    [113.9359452, 22.5218569],
				    [113.9408402, 22.5206243],
				    [113.9409046, 22.5205918],
				    [113.9409457, 22.5205707],
				    [113.9409801, 22.5205532],
				    [113.9410334, 22.5205264],
				    [113.9414433, 22.5203182]
				]
			}
		}
	]
}

1.2 道路路面数据

\quad 道路路面数据为面类型数据,描述的是实际道路的外观,由于道路的几何信息较为复杂,通常在需要显示道路细节数据时,才显示道路路面数据。道路路面如下图所示:

在这里插入图片描述

\quad 道路路面数据以 GeoJSON 格式存储在文件中,一条道路由多个 GeoJSON 对象组成。该对象主要信息就是道路路面的坐标数据,由features 属性中的 coordinates 属性指定,此外该 GeoJSON 对象中也包含了crs属性。

\quad 在测绘道路路面多边形数据时,由于比例尺不同,测绘的精度会有很大差异,对于大比例尺的数据,在某些复杂的十字路口,其面数据的坐标点甚至可能会达到甚至超过数百个点,因此在不需要显示道路细节时,往往会以显示道路中心线的方式代替显示道路路面,不仅仅加快了渲染速度,而且是的图形画面更为简洁,可更好突出图形主体信息。道路路面 GeoJSON 对象如下所示:

{
	"type": "FeatureCollection",
	"crs": {
		"type": "name",
		"properties": {
			"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
		}
	},
	"features": [
		{
			"type": "Feature",
			"id": "1-2000007-F",
			"geometry": {
				"type": "Polygon",
				"coordinates": [[
                    [113.9440488, 22.5358627],
                    [113.9424885, 22.5358365],
                    [113.9419384, 22.5358351],
                    [113.9419385, 22.5357417],
                    [113.9424895, 22.5357431],
                    ……
                    [113.9440506, 22.5357693]
				]]
			}
		}
	]
}

1.3 道路虚线数据

\quad 道路虚线数据为线类型数据,描述的交通部门在实际道路路面中绘制的虚线,表示车辆可以变道数据,下图在道路路面中显示了道路虚线:

在这里插入图片描述

\quad 道路虚线数据以 GeoJSON 格式存储在文件中,一条道路包含了多个 GeoJSON 虚线对象。该对象主要信息就是道路虚线的坐标数据,由features 属性中的 coordinates 属性指定,此外该GeoJSON 对象中也包含了crs属性。道路虚线 GeoJSON 对象如下所示:

{
	"type": "Feature",
	"id": "1-2000007-1",
	"geometry": {
		"type": "LineString",
		"coordinates": [
			[113.94405, 22.5358002],
			[113.9424891, 22.535774],
			[113.9419385, 22.5357726]
		]
	}
}

1.4 道路实线数据

\quad 道路实线数据为线类型数据,描述的交通部门在实际道路路面中绘制的实线,表示车辆不可以变道数据,下图在道路路面中显示了道路实线:

在这里插入图片描述

\quad 道路实线数据以 GeoJSON 格式存储在文件中,一条道路包含了多个 GeoJSON 实线对象。该对象主要信息就是道路实线的坐标数据,由features 属性中的 coordinates 属性指定,此外该GeoJSON 对象中也包含了crs属性。道路实线 GeoJSON 对象如下所示:

{
	"type": "Feature",
	"id": "1-2000007-0",
	"geometry": {
		"type": "LineString",
		"coordinates": [
			[113.9440506, 22.5357686],
			[113.9424895, 22.5357424],
			[113.9419385, 22.535741]
		]
	}
}

1.5 道路路面方向指示箭头数据

\quad 道路路面方向指示箭头数据为点类型数据,描述的交通部门在实际道路路面中绘制的方向箭头,用于提示驾驶员车辆可前进的方向,下图在道路路面中显示了道路路面方向指示箭头:

在这里插入图片描述

\quad 道路路面方向指示箭头数据以 GeoJSON 格式存储在文件中,一条道路包含了多个 GeoJSON 方向指示箭头对象。

\quad 该对象中不仅包含了方向指示箭头的坐标数据,还在特征属性中包含了指示箭头的符号,该符号是png位图格式,下面这个 GeoJSON 对象中, properties 属性中的 symbol 属性指的是 符号对应的位图文件名称,angle 属性指定该符号的旋转角度(单位:弧度), features 属性中的 coordinates 属性指的是该方向指示箭头的坐标。此外该 GeoJSON 对象中也包含了 crs 属性。

\quad 道路路面方向指示箭头 GeoJSON 对象如下所示:

{
	"type": "FeatureCollection",
	"crs": {
		"type": "name",
		"properties": {
			"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
		}
	},
	"features": [
		{
			"type": "Feature",
			"id": "1-6000000-T0",
			"properties": {
				"symbol": "1200-0",
				"angle": "-1.491277",
				"size": "2.000000"
			},
			"geometry": {
				"type": "Point",
				"coordinates": [113.9446868, 22.5244148]
			}
		}
	]
}

2 功能实现

\quad 在本示例中,我们将实现交通路网数据的显示、图形平移和缩放、指定初始图形视点、分层控制、根据缩放级别显示相应图层等功能。

2.1 初始视点

\quad anyGraph 的最核心类为 Graph,图形的展示均从创建该类的实例开始。在第七章 图形交互操作: 视点控制与动画中讲述了“图形初始化时控制视点”的内容,当初始化视点为显示全图时,可在实例化Graph时通过fullView=true 进行设置。

\quad 以下为实例化 Graph 类,并将初始视点设置为显示全图的代码:

//初始化graph对象,初始视点为显示全图
let graph = new Graph({
    "target": "graphWrapper",
    "originAtLeftTop": false,
    "fullView":true
});

\quad 目前许多地图应用,其初始视点通常设置位当前的位置,下面我们来实现这个功能。

\quad 我们首先来分析一下样式数据, 在将WGS84坐标转换为WEB墨卡托投影坐标后,本样例数据的坐标范围为:[12683000, 2574000, 12685600, 2577400],其最大宽度为2600米,最大高度为3400米。目前比较主流的的屏幕分辨率为 1920 × 1080 1920 \times 1080 1920×1080 ,在减去浏览器标题和工具栏等位置后,其最大可用范围约为 1900 × 960 1900 \times 960 1900×960 。 在第五章 图形交互操作:平移和缩放中我们讲述了图形分辨率是图形坐标系与像素坐标系的比值,因此在主流的屏幕中当显示全图时,其分辨率为 2600 ÷ 1900 2600 \div 1900 2600÷1900 3400 ÷ 960 3400 \div 960 3400÷960 的较大值,即为 3.54 3.54 3.54

\quad 最大分辨率为3.54,初始化时通常显示的是一个较小的范围,因此我们假设缺省分辨率为1.2。

\quad 通过浏览器全局变量 navigator 可获取到当前的地理位置坐标,由于样例数据的范围比较小,我们假设一个指定的坐标就是我们当前的位置。

\quad 以下为实例化 Graph 类,并将初始视点设置为指定的位置和大小的代码:

let currentCoord = [12684305, 2576407];
let defaultResolution = 1.2;

// 初始化graph对象,指定视点位置
let graph = new Graph({
    "target": "graphWrapper",
    "originAtLeftTop": false,
    "view": new View({
        center: currentCoord,              //地图初始中心点
        resolution: defaultResolution      //地图初始显示密度
    })
});

2.2 装载数据

\quad 在第二章 图形管理类(Graph)中讲述图层的概念,图层(Layers)是一种用于组织和管理图像内容的办法。图层可以将不同的图像元素分开,使得它们可以独立地进行绘制、编辑和操作。

\quad 在本示例中,根据数据的特诊,可将交通路网图形划分为以下几层:

交通路网
道路中心线
道路路面
道路虚线
道路实线
路面方向指示箭头
道路路名
道路中心线层

\quad 道路中心线数据为线类型数据,由于其几何信息较为简单,通常在仅需显示道路位置和走向的时候使用,而在显示道路更为详细的数据时需切换显示道路路面数据。

\quad 在第三章 图层类(Layer)中讲述图层控制的可见性时,讲述过在构造函数中可通过最小分辨率 minResolution 和 最大分辨率 maxResolution 属性来控制图层可见性。

\quad 以下为实例化道路路中线图层,设置了 minResolution = 1.88,这就意味着在图形缩放时,当前分辨率大于等于 1.88 时将会显示该图层,当前分辨率小于 1.88 时将不显示该图层。

let projection = new WebMercator();
let path = "../../data/sz_road_part/";

// 图层:道路-路中线
let layerRoadCenter = new Layer({
    source: new VectorSource({
        "fileUrl": path + "export_roadcenter.geojson",
        "projection": projection,
        "format": new GeoJSONFormat()
    }),
    zIndex: 24,
    name: "道路-路中线",
    style: { "color": "#999900", "lineWidth": 10 },
    minResolution: 1.880,
    visible: true
});
graph.addLayer(layerRoadCenter);
道路路面层

\quad 刚刚我们分析到,在显示道路路中线图层时不显示道路路面图层,而当不显示道路路中线图层时,则需要显示道路路面图层。这个功能依旧通过设置分辨率来实现。

\quad 对于道路路面,需设置当分辨率小于 1.88 时才进行显示,因此需要通过属性 maxResolution 来控制。以下代码中设置了 maxResolution = 1.88,这就意味着在图形缩放时,当前分辨率小于 1.88 时才会显示该图层。

// 图层:道路-路面
let layerRoadFace = new Layer({
    source: new VectorSource({
        "fileUrl": path + "export_redge_face.geojson",
        "projection": projection,
        "format": new GeoJSONFormat()
    }),
    zIndex: 10,
    name: "道路-路面",
    style: { "color": "rgba(48, 48, 48, 1)", "fillColor": "rgba(48, 48, 48, 1)", "fillStyle": 1, "lineWidth": 0 },
    maxResolution: 1.880
});
graph.addLayer(layerRoadFace);

下图为运行效果:

在这里插入图片描述

道路虚线层

\quad 道路虚线层显示时必须依附于道路路面,否则就没有意义,因此仍需通过分辨率来控制图层显示。由于道路路面层的最大显示分辨率为 1.88 ,因此道路虚线层的最大分比率也必须设置为小于 1.88时才显示出来 。由于分辨率为1.88时,其路面还很窄小,因此下面这段代码中将 maxResolution 设置为了 0.62

\quad 在第三章 图层类(Layer)中讲述图层的样式,在渲染图层中的数据对象时,既可以为图层中的每一个数据对象指定样式,也可以为图层指定样式。如果数据对象和图层均指定了样式,则数据对象的样式优先。在这几个图层中均是在实例化 DataSource 时通过指定 fileUrl 装载数据,由于 GeoJSON 数据中是不包含样式信息的,因此均是通过指定图层样式指定图形对象的渲染样式。

\quad 对于道路虚线层,不仅仅需要指定线的颜色和线宽,还需指定线型为虚线,其代码如下:

// 图层:道路-虚线
let layerRoadDash = new Layer({
    source: new VectorSource({
        "fileUrl": path + "export_line_dash.geojson",
        "projection": projection,
        "format": new GeoJSONFormat()
    }),
    zIndex: 18,
    name: "道路-虚线",
    style: { "color": "#FFFFFF", "dash": [6, 6, 6, 6], "lineWidth": 1 },
    maxResolution: 0.62
});
graph.addLayer(layerRoadDash);
道路实线层

\quad 道路实线层显示属性和道路虚线层类似,也必须依附于道路路面,因此也将 maxResolution 设置为了 0.62 ,其图层样式均需设置线的颜色和线宽,缺省线型即为实线。其代码如下:

// 图层:道路-实线
let layerRoadLine = new Layer({
    source: new VectorSource({
        "fileUrl": path + "export_line.geojson",
        "projection": projection,
        "format": new GeoJSONFormat()
    }),
    zIndex: 20,
    name: "道路-实线",
    style: { "color": "white", "lineWidth": 1 },
    maxResolution: 0.62
});
graph.addLayer(layerRoadLine);
道路路面方向指示箭头层

\quad 在第四章:图形基本形状中讲述了图形系统中常见的基本形状包括:点、折线、多边形、矩形、圆形、文本、图像等类型。在上面的这几个图层中 “道路路面” 对应的基本形状为 多边形、“道路中心线”、“道路虚线”、“道路实线” 对应的基本形状为 折线类型,而 “道路路面方向指示箭头” 对应的基本形状为点类型

\quad 点类型在渲染时通常会渲染为三角形等常见的几何形状,而 anyGraph 在渲染点时还提供了内置类型图标两种渲染方式。内置类型包括了正方形、正五边形、正六边形、四角星、五角星、笑脸、花朵等形状;而图形类型则会将点渲染为位图图标,从而渲染出更为丰富的形状。下图为anyGraph 提供的 内置类型

在这里插入图片描述

下图为anyGraph 渲染的 图标

在这里插入图片描述

\quad 道路路面方向指示箭头为点数据类型,其数据对象的properties 属性中包含了 symbol 属性指定符号对应的位图文件名称,angle 属性指定该符号的旋转角度(单位:弧度)。这些符号显示效果如下图所示:

在这里插入图片描述

\quad 由于 symbolangle 属性并非 GeoJSON 格式的标准属性,因此 GeoJSONFormat 并不会将这两个属性加载到数据对象中。可手动调用 VectorSource 类的 loadFile()方法,在其回调函数中指定点对象的srcrotation属性,从而将其渲染为位图。

\quad 道路路面方向指示箭头也必须依附于道路路面,可在实线和虚线渲染后在进行渲染,因此将 maxResolution 设置为了 0.4。初始化道路路面方向指示箭头层的代码如下:

// 图层:地面方向箭头指示
let layerRoadTurn = new Layer({
    source: new VectorSource({
        "projection": projection,
        "format": new GeoJSONFormat()
    }),
    zIndex: 40,
    name: "地面方向箭头指示",
    style: { "color": "#DAA520", "size": 16, "centerAsOrigin": true },
    maxResolution: 0.4,
    visible: true
});
graph.addLayer(layerRoadTurn);

// 加载地面方向箭头数据
layerRoadTurn.getSource().loadFile(path + "export_turn.geojson", function (file) {
    let datas = layerRoadTurn.getSource().getData();
    if (datas.length > 0) {
        // 根据geom的properties修改geom的属性
        datas.forEach(obj => {
            let symbol = obj.properties.symbol;
            let idx = symbol.indexOf("-");
            let fileName = (idx > 0) ? symbol.substring(0, idx) : symbol;
            obj.src = path + "images/" + fileName + ".png";
            obj.rotation = MathUtil.toDegrees(obj.properties.angle);
            layerRoadTurn.getSource().add2Cache(obj.imgUrl);
        })
    }
});

\quad 由于默认情况下 anyGraph 图标点对象的大小不会随着图形的缩放而缩放,始终渲染为指定的大小,多边形则会随着图形的缩放而缩放。在本示例中,随着图形的放大,道路路面将随着放大,我们也希望道路路面方向指示箭头也能进行放大。这个需求可通过图层的动态样式功能来实现,动态样式本质上是一个回调函数,anyGraph 在图形渲染之前将调用该回调函数。因此可在该回调函数中修改图形对象的样式属性,实现动态样式的功能。增加动态样式后的代码如下所示:

// 图层:地面方向箭头指示
let layerRoadTurn = new Layer({
    source: new VectorSource({
        "projection": projection,
        "format": new GeoJSONFormat()
    }),
    zIndex: 40,
    name: "地面方向箭头指示",
    style: {
        "color": "#DAA520", "size": 16, "centerAsOrigin": true, "dynamicFn": function (obj, objStyle, viewState) {
            let res = 0.1;
            let scale = 0.3;
            if (viewState.resolution > res * Math.pow(2, 5)) {
                scale = scale * 0.125;
            } else if (viewState.resolution > res * Math.pow(2, 4)) {
                scale = scale * 0.25;
            } else if (viewState.resolution > res * Math.pow(2, 2)) {
                scale = scale * 0.5;
            } else if (viewState.resolution > res * Math.pow(2, 1)) {
                scale = scale * 1;
            } else if (viewState.resolution > res * Math.pow(2, 0)) {
                scale = scale * 2;
            } else if (viewState.resolution > res * 0.4) {
                scale = scale * 4;
            } else {
                scale = scale * 8;
            }
            objStyle.scale = scale;
            return true;
        }
    },
    maxResolution: 0.4,
    visible: true
});
graph.addLayer(layerRoadTurn);

// 加载地面方向箭头数据
layerRoadTurn.getSource().loadFile(path + "export_turn.geojson", function (file) {
    let datas = layerRoadTurn.getSource().getData();
    if (datas.length > 0) {
        // 根据geom的properties修改geom的属性
        datas.forEach(obj => {
            let symbol = obj.properties.symbol;
            let idx = symbol.indexOf("-");
            let fileName = (idx > 0) ? symbol.substring(0, idx) : symbol;
            obj.src = path + "images/" + fileName + ".png";
            obj.rotation = MathUtil.toDegrees(obj.properties.angle);
            layerRoadTurn.getSource().add2Cache(obj.imgUrl);
        })
    }
});

增加动态样式后的运行效果如下图所示:

在这里插入图片描述

2.3 路名标注

\quad 至此,交通路网所提供的的各类数据均已加载完毕了。然而目前的运行效果还缺少一些标注信息,能否将道路名称显示在道路上面呢?

\quad 在数据分析1.1中我们看到道路中心线数据中是包含道路名称的,可使用该数据显示道路名称。

\quad 由于道路中心线图层在初始化时设置了最小密度属性 minResolution = 1.88,这就意味着在图形缩放时,当前分辨率大于等于 1.88 时将会显示该图层,当前分辨率小于 1.88 时将不显示该图层。如果在该图层中显示标注,也将受到分辨率的限制,因此我们还需增加“道路名称” 图层,通过该层显示道路名称。

\quad anyGraph 的 基本图形形状 “折线” (Polyline) 不仅仅提供了绘制折线的功能,还为折线提供标注的功能。该功能可读取折线的 label 属性,以及折线样式中的 labelStyle属性,当这两者都存在时将绘制折线标注信息。

\quad 由于已经加载了道路路中线图层,为了避免重复绘制路中线,在“道路名称”图层中设置样式 lineWidth = -1,从而避免重复绘制折线。同时我们也为该图层设置了动态样式,随着图形的缩放,道路名称也将分几个层次显示。初始化“道路名称”图层的代码如下所示:

let layerRoadName = new Layer({
    source: new VectorSource({
        "fileUrl": path + "export_roadcenter.geojson",
        "projection": projection,
        "format": new GeoJSONFormat()
    }),
    zIndex: 50,
    name: "道路-道路名称",
    style: {
        "color": "#FFFFFF00",
        "lineWidth": -1,
        "labelStyle": { "font": "20px 黑体", "fillColor": "#FF9900" }, "dynamicFn": function (obj, objStyle, viewState) {
            let res = 1.88;
            let font;
            let fillColor;
            if (viewState.resolution > res * 2) {
                font = "14px 黑体";
                fillColor = "#000000";
            } else if (viewState.resolution > res) {
                font = "20px 黑体";
                fillColor = "#000000";
            } else if (viewState.resolution > res * 0.5) {
                font = "24px 黑体";
                fillColor = "#FF9900";
            } else if (viewState.resolution > res * 0.1) {
                font = "28px 黑体";
                fillColor = "#FF9900";
            } else {
                font = "32px 黑体";
                fillColor = "#FF9900";
            }
            objStyle.labelStyle.font = font;
            objStyle.labelStyle.fillColor = fillColor;
            return true;
        }
    },
    visible: true
});
graph.addLayer(layerRoadName);

\quad 增加 “道路名称” 图层后的运行效果如下图所示:

在这里插入图片描述

2.4 图形交互操作:平移和缩放

\quad 在第五章 图形交互操作:平移和缩放中讲述了图形缩放的原理,并讲述了 通过坐标转换实现图形平移缩放,以及通过Canvas渲染上下文对象提供的矩阵变换功能实现图形的平移和缩放功能。

\quad 在讲述通过坐标转换实现图形平移缩放功能时,讲述了比较简单的通过一次函数实现坐标转换功能,也讲述了通过更为通用的3阶矩阵实现平移缩放旋转的坐标转换方法,有兴趣的朋友们可以到那篇文章中复习这些内容。

\quad anyGraph 中分别采用这两种方法实现了图形的缩放与漫游功能,在初始化各图层后即提供了该功能,因此这部分功能无需添加任何代码,开箱即用。

2.5 控件

\quad anyGraph 作为一个成长中的矢量化图形系统二次开发组件,基本功能已基本完成了,而各种扩展功能也正在不断完善之中。以下代码为 交通路网图形增加了三个控件,分别为:图层控制控件、缩放操作控件、显示坐标位置控件。

// 图层控件
graph.addControl(new LayerControl());
graph.addControl(new MousePositionControl());
graph.addControl(new ZoomControl());

\quad 添加控件后的界面效果如下图所示:

在这里插入图片描述

图层控制

\quad 图层控制控件是一种用户界面组件,用于在图形中控制图层的显示和隐藏。通过选择或取消各图层名称前面的复选框,可以动态显示或隐藏图形中的图层,从而实现图形的定制和个性化展示。

缩放操作

\quad 缩放操作控件是一种用户界面组件,用于在图形中控制图层的放大和缩小。作为对鼠标缩放和手势缩放的补充,缩放操作控件更加简单和直观,它是基于中心点的缩放,在缩放时还伴有动画效果。

显示坐标位置

\quad 显示坐标位置控件是一种用户界面组件,用于在图形中显示当前鼠标或触摸点的坐标位置。使用显示坐标位置控件,用户可以在图形中快速了解当前位置的坐标。这对于需要精确定位或测量图形上的距离和面积的应用场景非常有用。

2.6 效果展示

初始界面

初始显示指定坐标和密度的位置,如下图所示:

在这里插入图片描述

显示道路路中线

执行图形缩小操作后,显示出整个路网的全图,此时仅显示道路路中线和道路名称,如下图所示:

在这里插入图片描述

显示道路路面

逐渐放大图形,此时将显示出路面图形,同时隐藏道路路中线图层,如下图所示:

在这里插入图片描述

显示道路实线和虚线

继续放大图形,此时将显示出道路实线和道路虚线图层,如下图所示:

在这里插入图片描述

显示道路路面方向指示箭头

继续放大图形,此时将显示出道路路面方向指示箭头图层,如下图所示:

在这里插入图片描述

功能演示动画

下面这个gif,以动图方式演示了上述功能。

在这里插入图片描述


\quad “图形系统实战开发-进阶篇 第十章 应用实例:交通路网” 的内容讲解到这里就结束了,如果觉得对你有帮助有收获,可以关注我们的官方账号,持续关注更多精彩内容。

相关资料

▶ 系列教程及代码资料:https://GraphAnyWhere.com
▶ 图形系统开发实战课程:进阶篇(上)——前言
▶ 图形系统开发实战课程:进阶篇(上)——1.基础知识
▶ 图形系统开发实战课程:进阶篇(上)——2.图形管理类(Graph)
▶ 图形系统开发实战课程:进阶篇(上)——3.图层类(Layer)
▶ 图形系统开发实战课程:进阶篇(上)——4.图形基本形状
▶ 图形系统开发实战课程:进阶篇(上)——5.图形交互操作:平移和缩放
▶ 图形系统开发实战课程:进阶篇(上)——6.图形交互操作:拾取
▶ 图形系统开发实战课程:进阶篇(上)——7.图形交互操作: 视点控制与动画
▶ 图形系统开发实战课程:进阶篇(上)——8.图形样式
▶ 图形系统开发实战课程:进阶篇(上)——9.空间算法(一)


作者信息

作者 : 图形开发学院
CSDN: https://blog.csdn.net/2301_81340430?type=blog
官网:https://graphanywhere.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/437641.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

老师如何发布已点评的学生在校表现,并让家长留言反馈?

教师想要在线上发布已点评过的成绩单,同时想让家长在线留言反馈,还要做到只能查自己孩子的成绩,应该如何实现? 可以使用易查分制作一个学生在校表现查询系统,家长自主查询,有问题可留言向班主任反馈&#x…

什么是工业协议网关?作用是什么?

在工业自动化和智能制造领域,数据的采集、传输和处理是实现设备监控、远程控制和优化的关键。而工业协议网关,作为连接工业设备与上层管理系统的桥梁,发挥着至关重要的作用。今天,我们就来深入解析一下HiWoo Box这一工业协议网关的…

银行数字化转型导师坚鹏:银行数字化转型案例研究

银行数字化转型案例研究 课程背景: 数字化背景下,很多银行存在以下问题: 不清楚银行科技金融数智化案例? 不清楚银行供应链金融数智化案例? 不清楚银行普惠金融数智化案例? 不清楚银行跨境金融数智…

ACM题解Day10|总结篇|进制转化,GCD ,LCM ,二分答案

🔥博客介绍: 27dCnc [Cstring中find_first_not_of()函数和find_last_not_of()函数-CSDN博客] 方差,期望 概率 今日打卡: 算法周总结 ACM题解Day3| To Crash or not To Crash,Integer Prefix ,I don’t want to pay for the Late Jar-CSDN博客 第3题:…

温室气体排放控制中的DNDC模型建模技术及双碳应用

由于全球变暖、大气中温室气体浓度逐年增加等问题的出现,“双碳”行动特别是碳中和已经在世界范围形成广泛影响。国家领导人在多次重要会议上讲到,要把“双碳”纳入经济社会发展和生态文明建设整体布局。同时,提到要把减污降碳协同增效作为促…

蓝牙 | 软件: Qualcomm BT Audio 问题分析(4)----检查MIPS使用情况

大家好! 我是“声波电波还看今朝”成员的一位FAE Devin.wen,欢迎大家关注我们的账号。 今天给大家大概讲解“如何排查Qualcomm BT Audio”的疑难杂症(四):MIPS检查。 如果大家还没有注册我们大大通的账号&#xff0c…

彻底理解Java并发:乐观锁、悲观锁和CAS

一、悲观锁与乐观锁 锁的一种宏观分类方式是悲观锁和乐观锁。悲观锁与乐观锁并不是特指某个锁(Java 中没有哪个 Lock 实现类就叫 PessimisticLock 或 OptimisticLock),而是在并发情况下的两种不同策略。 1、乐观锁(Optimistic L…

RK3568平台 USB数据包的收发格式

一.USB硬件拓扑结构 compound device :多个设备组合起来,通过HUB跟Host相连composite device :一个物理设备有多个逻辑设备(multiple interfaces) 在软件开发过程中,我们可以忽略Hub的存在,硬件拓扑图简化如下&#x…

git revert 撤回之前的几个指定的提交

文章目录 Intro操作命令-n 选项 参考 Intro 在开发过程中,有的时候一开始只是一个小需求,可以改着改着事情超出了控制,比如说我一开始只是想调整一个依赖包的版本,可是改到后来类库不兼容甚至导致项目无法启动。 这个时候我就想&…

(二十二)devops持续集成开发——jenkins服务代理Agent搭建

前言 在Jenkins 中,代理(Agent)是一种用于执行构建、部署和其他任务的计算节点。代理节点可以是物理机器、虚拟机或容器,它们负责接收 Jenkins 主控节点委派的任务并执行这些任务。通过使用代理节点,可以有效地分担Je…

基于WebDriverAgent代理服务,实现iOS手机app自动化测试的框架搭建

🔥 交流讨论:欢迎加入我们一起学习! 🔥 资源分享:耗时200小时精选的「软件测试」资料包 🔥 教程推荐:火遍全网的《软件测试》教程 📢欢迎点赞 👍 收藏 ⭐留言 &#x1…

[数据结构初阶]队列

鼠鼠我呀,今天写一个基于C语言关于队列的博客,如果有兴趣的读者老爷可以抽空看看,很希望的到各位老爷观点和点评捏! 在此今日,也祝各位小姐姐女生节快乐啊,愿笑容依旧灿烂如初阳,勇气与童真永不…

每日五道java面试题之springMVC篇(一)

目录: 第一题. 什么是Spring MVC?简单介绍下你对Spring MVC的理解?第二题. Spring MVC的优点第三题. Spring MVC的主要组件?第四题. 什么是DispatcherServlet?第五题. 什么是Spring MVC框架的控制器? 第一题. 什么是S…

JavaScript 作用域详解:如何影响变量生命周期

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Linux系统——Keepalive群集部署及认识

目录 一、Keepalive的认识 1.Keepalive基础——VRRP 2.Keepalived工具介绍 2.1Keepalived介绍 2.2Keepalived架构 2.2.1用户空间核心组件 2.2.2WatchDog:监控进程(整个架构是否有问题) 二、安装Keepalived及相关配置文件详解 1.安装…

python 输入和输出

在 Python 中,输入和输出是最基本的操作之一。你可以使用内置函数 input() 来获取用户输入,使用 print() 函数来输出信息到控制台。 输入(Input) input() 函数用于从用户那里获取输入。这个函数会将用户的输入作为字符串返回。 示…

【C语言】终の指针(前篇)

个人主页点这里~ 指针初阶点这里~ 指针初阶2.0点这里~ 指针进阶点这里~ 终の指针 一、回调函数二、qsort函数1、整形比较2、结构数据比较①结构体②-> 的使用③结构数据比较 一、回调函数 回调函数就是⼀个通过函数指针调用的函数。 把一个函数的指针作为参数传递给另一…

分类预测 | Matlab基于GWO-RBF灰狼算法优化径向基神经网络的分类预测

分类预测 | Matlab基于GWO-RBF灰狼算法优化径向基神经网络的分类预测 目录 分类预测 | Matlab基于GWO-RBF灰狼算法优化径向基神经网络的分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 Matlab基于GWO-RBF灰狼算法优化径向基神经网络的分类预测。基于灰狼算法(GWO…

和为K的子数组

题目: 使用前缀和的方法可以解决这个问题,因为我们需要找到和为k的连续子数组的个数。通过计算前缀和,我们可以将问题转化为求解两个前缀和之差等于k的情况。 假设数组的前缀和数组为prefixSum,其中prefixSum[i]表示从数组起始位…

仓储管理系统(WMS) 的研发历程-PRD撰写

题外话:PRD的展现形式有多种,有的人喜欢在axure上直接做产品描述,觉得word较为过时,有的人认为axure不专业,任何展现形式都无可厚非,重要的达到PRD的目的,PRD的目标是让团队知道需求实现细节&am…