leaflet【八】 加载文件资源

本文将探讨如何使用Leaflet插件加载GPX和KML文件,并将文件内容解析并渲染到地图上。我们将介绍如何使用对应的插件来处理这两种常见的地理数据格式,以及如何将它们集成到Leaflet中。通过深入分析插件的工作原理和使用方法,我们将展示如何在地图上呈现这些文件的内容。此外,我们还将探讨一些高级技巧,以优化文件的加载和渲染过程。无论您是初学者还是有经验的开发者,本文都将为您提供宝贵的见解和实用的方法。让我们一起探索Leaflet的强大功能吧!

加载GPX

GPX 文件格式是 GPS Exchange Format,是一种用于交换 GPS
数据的格式。它可以用来描述路点、轨迹、路程。这个格式是免费的,可以在不需要付任何许可费用的前提下使用。它的标签保存位置,海拔和时间,可以用来在不同的GPS设备和软件之间交换数据。如查看轨迹、在照片的exif数据中嵌入地理数据。

安装插件

加载GPX文件可以使用leaflet-gpx插件。插件的demo案例

npm install leaflet-gpx

使用插件

  • 可以从下面的链接下载gpx文件,这里下载之后放在了本地所以就填路径进行加载了。
  • 创建的dpx对象也是一个layer,通过loaded等待异步加载完成添加到地图上即可。
import 'leaflet-gpx';

const loadGpx = () => {
  // 数据来源 https://mpetazzoni.github.io/leaflet-gpx/demo.gpx
  const url = './gpx/load.gpx';
  const gpx = new L.GPX(url, {
    async: true, marker_options: {
      startIconUrl: null,
      endIconUrl: null,
      shadowUrl: null
    },
    polyline_options: {
      color: '#f40',
      weight: 4,
      opacity: 1
    }
  }).on('loaded', (e) => {
    map.fitBounds(e.target.getBounds());
  }).addTo(map);
};

在这里插入图片描述

配置对象说明

e.target方法

方法说明
get_name()GPX 轨道的名称
get_distance()总轨道距离(以米为单位)
get_start_time()开始时间
get_end_time()结束时间
get_moving_time()返回移动时间,以毫秒为单位
get_total_time()返回总跟踪时间(以毫秒为单位)
get_moving_pace()返回平均移动速度(以毫秒/公里为单位)
get_moving_speed()返回平均移动速度(公里/小时)
get_total_speed()返回平均总速度(公里/小时)
get_elevation_min()返回最低高程(以米为单位)
get_elevation_max()返回最高海拔,以米为单位
get_elevation_gain()返回累积高程增益(以米为单位)
get_elevation_loss()返回累积高程损失,以米为单位
get_speed_max()返回最高速度(公里/小时)
get_average_hr()返回平均心率(如果可用)
get_average_cadence()返回平均节奏(如果可用)
get_average_temp()返回温度的平均值(如果可用)

如果您不喜欢公制,您还可以使用以下方法 任您使用:

方法说明
get_distance_imp()返回总航迹距离(以英里为单位)
get_moving_pace_imp()返回平均移动速度(以毫秒为单位) 小时
get_moving_speed_imp()返回平均移动速度(以英里/小时为单位)
get_total_speed_imp()返回平均总速度(以英里/小时为单位)
get_elevation_min_imp()返回最低海拔(以英尺为单位)
get_elevation_max_imp()返回最高海拔,以英尺为单位
get_elevation_gain_imp()返回累积高程增益(以英尺为单位)
get_elevation_loss_imp()返回累积高程损失(以英尺为单位)
get_speed_max_imp()返回最高速度(以英里/小时为单位)

插件源码分析

插件源码位于:node_modules/leaflet-gpx/gpx.js

简单说明(对代码也进行了简化,只贴出来一些核心代码)

  • 入口开始从initialize初始化开始,将options配置保存,将gpxinfo对象初始化。
  • 开始执行_parse方法,将gpx文件解析成xml对象,然后调用_parse_gpx_data方法进行解析。
  • 开始解析gpx对象
    • 先获取gpx标签下的name、desc、author、copyright等标签信息,保存到gpxinfo对象中。
    • 解析经纬度相关信息
    • 得到点信息,再去创建L.marker,将所有的的点信息添加到layers数组中。
    • 向外抛出addpoint事件,并将marker反传回去。
  • 最后在_parse当中将layers数组添加到地图上。并且抛出loaded事件。将layers数组、gpxinfo对象抛出。
  • 补充一:reload方法,重新加载gpx文件。也就是重新创建对象重新解析渲染
  • 补充二:为什么会有这么多方法可以获取到gpx对象?这是在解析的时候会将gpx对象保存到gpxinfo对象中,在loaded事件中抛出gpxinfo,也就可以获取到了。
L.GPX = L.FeatureGroup.extend({
  initialize: function (gpx, options) {
    // 保存options配置信息......

    // 初始化gpxinfo对象,用于后续存储等操作.......

    if (gpx) {
      // 开始解析gpx文件......
      this._parse(gpx, options, this.options.async);
    }
  },
  _parse: function (input, options, async) {
    var _this = this;
    var cb = function (gpx, options) {
      var layers = _this._parse_gpx_data(gpx, options);
      _this.addLayer(layers);
      _this.fire('loaded', {layers: layers, element: gpx});
    };
    if (input.substr(0, 1) === '<') {
      var parser = new DOMParser();
      // 通过了入参的async配置,如果为true,则异步加载,否则同步加载。最终执行解析......
      cb(parser.parseFromString(input, 'text/xml'), options);
    } else {
      this._load_xml(input, cb, options, async);
    }
  },
  _parse_gpx_data: function (xml, options) {
    var i, t, l, el, layers = [];

    // 解析标签当中的name、desc、author、copyright存到gpxinfo当中......

    // 解析经纬度相关信息
    if (parseElements.indexOf('waypoint') > -1) {
      el = xml.getElementsByTagName('wpt');
      for (i = 0; i < el.length; i++) {
        var ll = new L.LatLng(
          el[i].getAttribute('lat'),
          el[i].getAttribute('lon'));

        // 把每一个点的信息记录一下 ......

        // 创建起始点的marker ......
        var marker = new L.Marker(ll, {
          clickable: options.marker_options.clickable,
          title: name,
          icon: symIcon,
          type: 'waypoint'
        });
        marker.bindPopup('<b>' + name + '</b>' + (desc.length > 0 ? '<br>' + desc : '')).openPopup();
        this.fire('addpoint', {point: marker, point_type: 'waypoint', element: el[i]});
        layers.push(marker);
      }
    }

    if (layers.length > 1) {
      return new L.FeatureGroup(layers);
    } else if (layers.length == 1) {
      return layers[0];
    }
  },
  reload: function () {
    this._init_info();
    this.clearLayers();
    this._parse(this._gpx, this.options, this.options.async);
  }
});

加载KML

KML,是标记语言(Keyhole Markup Language)的缩写,最初由Keyhole公司开发,是一种基于XML
语法与格式的、用于描述和保存地理信息(如点、线、图像、多边形和模型等)的编码规范,可以被 Google Earth 和 Google Maps 识别并显示。
Google Earth 和 Google Maps 处理 KML 文件的方式与网页浏览器处理 HTML 和 XML 文件的方式类似。像 HTML 一样,KML
使用包含名称、属性的标签(tag)来确定显示方式。因此,您可将 GoogleEarth和 Google Maps 视为 KML文件浏览器。
2008年4月微软的OOXML成为国际标准后,Google公司宣布放弃对KML的控制权,由开放地理信息联盟(OGC)接管KML语言,并将“Google
Earth”及“Google Maps”中使用的KML语言变成为一个国际标准。

安装插件

加载KML文件可以使用leaflet-kml插件。插件的demo案例,并且也可以从这个上面获取一些KML文件进行测试

npm install leaflet-kml

可以用这个kml测试一下

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
	<name>kml_2.kml</name>
	<Style id="style">
		<LineStyle>
			<color>ff0000ff</color>
			<width>4</width>
		</LineStyle>
		<PolyStyle>
			<color>b0ff00ff</color>
			<fill>0</fill>
		</PolyStyle>
	</Style>
	<Style id="style0">
		<LineStyle>
			<color>ff0000ff</color>
			<width>4</width>
		</LineStyle>
		<PolyStyle>
			<color>b0ff00ff</color>
			<fill>0</fill>
		</PolyStyle>
	</Style>
	<StyleMap id="stylemap_id0">
		<Pair>
			<key>normal</key>
			<styleUrl>#style</styleUrl>
		</Pair>
		<Pair>
			<key>highlight</key>
			<styleUrl>#style0</styleUrl>
		</Pair>
	</StyleMap>
	<Placemark id="kml_2">
		<name>kml_2</name>
		<styleUrl>#stylemap_id0</styleUrl>
		<Polygon>
			<outerBoundaryIs>
				<LinearRing>
					<coordinates>
						55.4166543623542,25.1320969293713,0 55.41681698167179,25.1328561251655,0 55.4163984553963,25.1333265025189,0 55.4168676483967,25.1336740703039,0 55.41722900084591,25.1332679440844,0 55.4181090049688,25.1331744980698,0 55.4207677072356,25.1351439219491,0 55.4215660884208,25.1357281294205,0 55.4246021505057,25.1383086596904,0 55.4246745060837,25.1402295529956,0 55.4222804342472,25.143487942228,0 55.4228230215679,25.1439708106181,0 55.4254857325771,25.1418051451684,0 55.4295293355549,25.1421681262853,0 55.4300105578506,25.1422113155951,0 55.4334451879316,25.1444655788254,0 55.4350461823124,25.1456527239196,0 55.4351608085304,25.1471574512235,0 55.4352432808011,25.1482398193707,0 55.4345182734431,25.1492019706079,0 55.4349359684783,25.149652475826,0 55.4365433135578,25.1491411787166,0 55.437777579949,25.149097690906,0 55.4396054923085,25.1490332677837,0 55.4501137688674,25.1568233384533,0 55.45013666003379,25.1582600565441,0 55.44881095332569,25.159019285467,0 55.44927932923051,25.1597338370787,0 55.4508781369843,25.1588096732073,0 55.4527425503435,25.1587720814486,0 55.4550584249575,25.1604886996999,0 55.4552036360527,25.160598460205,0 55.4553533981856,25.1607162240046,0 55.455500524908,25.1608367070329,0 55.45564497647479,25.1609598371125,0 55.4557866834285,25.1610855872265,0 55.4559255961123,25.1612138942329,0 55.4560616450492,25.1613447130608,0 55.4561948004184,25.1614779805517,0 55.4563249828315,25.1616136606701,0 55.4564521525382,25.1617516812387,0 55.4565762598867,25.1618919881429,0 55.45669725523379,25.1620345362951,0 55.4568150790071,25.1621792715891,0 55.456929701363,25.1623261128116,0 55.45704106274611,25.1624750239109,0 55.4571491234013,25.1626259327091,0 55.4572538336723,25.1627787850914,0 55.4573551637308,25.1629335178988,0 55.45745305399059,25.1630900679974,0 55.4575474845412,25.1632483722197,0 55.4576384156329,25.1634083674147,0 55.4577257975876,25.1635699814123,0 55.4578096005919,25.1637331691075,0 55.4578898047139,25.1638978492777,0 55.4579659825138,25.1640631285891,0 55.4580250589022,25.1641980635637,0 55.45808157680891,25.1643335061945,0 55.45813569523491,25.1644697542502,0 55.4581873943075,25.1646067806683,0 55.4582366541447,25.1647445493592,0 55.4582834747022,25.164883024216,0 55.4583278261693,25.1650221601301,0 55.4583697184389,25.1651619390408,0 55.4584091216907,25.1653023068116,0 55.458446035889,25.1654432363628,0 55.4569313444796,25.1676172626881,0 55.4550085065534,25.1681892431239,0 55.45274709818661,25.1688619003742,0 55.4501304577272,25.1693587541307,0 55.45011810621411,25.1693048801494,0 55.4500589149044,25.1693161192138,0 55.45007126799,25.1693699947725,0 55.4456133180576,25.170216467488,0 55.44586030146801,25.1712937974163,0 55.44875612126269,25.1707440811347,0 55.4530178561411,25.1699349598812,0 55.4573433579315,25.1696890446798,0 55.4596127116737,25.1711930263905,0 55.4610382375249,25.175688703172,0 55.46186575417931,25.1793193603929,0 55.4619914696023,25.1799195811167,0 55.4621096480917,25.1805210720543,0 55.4622204891363,25.1811249614558,0 55.4624922508461,25.1826595906771,0 55.4628171025677,25.1873390732353,0 55.4650912494022,25.1869432161445,0 55.46487927203711,25.1862359322509,0 55.4647318087049,25.1857439016305,0 55.4645217185145,25.1850428983799,0 55.4641715768856,25.1838745576656,0 55.4641015503582,25.1836408884944,0 55.4640804172562,25.1835703716897,0 55.4640049115418,25.1831440366236,0 55.46382343101541,25.1821193057038,0 55.4636939278165,25.1813880551245,0 55.46360759239441,25.18090055500859,0 55.4634593708225,25.1801728276571,0 55.4632514982602,25.1791485927304,0 55.46311152903511,25.1784589243766,0 55.46302909776941,25.17809899223951,0 55.4628550416876,25.1773389780978,0 55.462679627426,25.1765730249231,0 55.46253313144519,25.175933332944,0 55.4624666826232,25.1756431749609,0 55.4623608654544,25.1751811091925,0 55.4621671329984,25.1739209707666,0 55.4619716079898,25.1726491329671,0 55.4618202454872,25.171664511557,0 55.4616688866941,25.1706798909788,0 55.4616133356539,25.1703185148032,0 55.4615458199577,25.169879343009,0 55.4622620262767,25.1688840072807,0 55.462546952885,25.168488029308,0 55.4648326255306,25.1677154044986,0 55.4651649719228,25.1676225721216,0 55.46977141991619,25.1668495015539,0 55.47208045564781,25.1664114201373,0 55.4728719476588,25.1662753215121,0 55.47366711006239,25.1661583439445,0 55.4744654076849,25.1660605781577,0 55.4748655513193,25.1660189235358,0 55.47566748133599,25.1659501072497,0 55.4764711391272,25.1659006393973,0 55.48090690769569,25.1657111623576,0 55.4895568606323,25.1653426958492,0 55.4997149687432,25.1684052907248,0 55.5180103750279,25.1826184962432,0 55.5209223430229,25.1795141282093,0 55.50626379486501,25.1681269474336,0 55.5038382913153,25.1662423910883,0 55.5032016886573,25.1650141255922,0 55.5037223018574,25.1650092445346,0 55.5042424451848,25.1649885369889,0 55.5047615378491,25.1649520260779,0 55.505279000234,25.1648997525706,0 55.5057942545457,25.1648317748359,0 55.50630672545861,25.1647481687781,0 55.5068158407581,25.1646490277516,0 55.50732103198051,25.1645344624566,0 55.5078217350482,25.1644046008154,0 55.5083173909,25.1642595878297,0 55.5088074461162,25.164099585418,0 55.5092913535366,25.1639247722351,0 55.51273827103739,25.1637613315798,0 55.5146435763895,25.1622650568936,0 55.5126995901551,25.1602146967406,0 55.5119894856175,25.1607723563843,0 55.5103217142403,25.1606111825497,0 55.5099930689467,25.1610752149103,0 55.50945575129,25.1623979146535,0 55.50904440615339,25.1625726703355,0 55.50862698670969,25.1627350594095,0 55.5082039416972,25.1628849072936,0 55.5077757259073,25.1630220528878,0 55.5073427996953,25.1631463487477,0 55.5069056284854,25.16325766124289,0 55.5064646822695,25.1633558707012,0 55.50602043510149,25.1634408715369,0 55.5055733645879,25.163512572365,0 55.505123951373,25.1635708960988,0 55.5051095554138,25.1634338880991,0 55.5013737256311,25.163339660741,0 55.5007644987945,25.1633242824076,0 55.4945697086387,25.1608491400579,0 55.4863797997356,25.1544838478528,0 55.4851450301533,25.1557998251419,0 55.486548412591,25.1571239169454,0 55.4883683611784,25.1589372345571,0 55.49110747338791,25.1617016669459,0 55.49015977504101,25.1636263016554,0 55.488693424463,25.1639087036606,0 55.48253952080439,25.1641708657218,0 55.48151213502781,25.1642145874302,0 55.4798604131903,25.164284982915,0 55.4794522433642,25.1643023936645,0 55.4774411283787,25.1643881558382,0 55.4754618704474,25.1644962082397,0 55.47526384415421,25.1645070176507,0 55.474882967755,25.1645394200322,0 55.4746127725381,25.1645665612936,0 55.474194464933,25.164611012904,0 55.4737232812457,25.1646668246406,0 55.4734817061745,25.1646985541427,0 55.4730467750413,25.1647587437382,0 55.4726669353539,25.1648165195918,0 55.4723737560501,25.1648641567427,0 55.4723161203447,25.1648735405336,0 55.472035482994,25.1649218016632,0 55.47175528444021,25.1649723457483,0 55.4707616163653,25.165160749621,0 55.46975167134651,25.1653523123433,0 55.4682260630079,25.1656424742796,0 55.4680702449642,25.1656720901783,0 55.4669524730677,25.1655028309811,0 55.46362102117051,25.1649983325492,0 55.46330985685659,25.164951185828,0 55.4582515252541,25.161202236908,0 55.4576587459622,25.160762882064,0 55.453855909317,25.1579441366992,0 55.4536378270504,25.1560708111995,0 55.4550851466512,25.1544532762101,0 55.4546631943445,25.1541405470572,0 55.4532835078981,25.1556824472297,0 55.4510819082667,25.1558878875231,0 55.4470559418253,25.1529035004414,0 55.44400597667861,25.1506424439185,0 55.4419801139678,25.1491405134437,0 55.44115120299329,25.14852596357269,0 55.43977965702369,25.147509065431,0 55.4396294903398,25.1471178448856,0 55.43983893163279,25.1468771875232,0 55.43941702115301,25.1465643668,0 55.4385787614774,25.1443805132531,0 55.43783159545819,25.1438193006964,0 55.4346573963547,25.14371105674009,0 55.43201975784881,25.1417551955512,0 55.4292064008226,25.1392384710256,0 55.4290165355486,25.137873394682,0 55.4295664574478,25.1369640744709,0 55.4306307478656,25.1352041789135,0 55.42954231550181,25.1352307528261,0 55.4284276270465,25.1361195260434,0 55.4277470734964,25.1366621624151,0 55.42756058304601,25.1368108750915,0 55.426212134525,25.1368764973804,0 55.42464486541021,25.1358949010643,0 55.4223214085329,25.1344396376519,0 55.4214198870008,25.1338749640066,0 55.42074554792389,25.1334525793813,0 55.4205591131717,25.1333358024855,0 55.4199229759232,25.1328656009953,0 55.41788567336319,25.1313596844375,0 55.4169000005746,25.1306288358363,0 55.41516338913389,25.12934114990029,0 55.4138769288464,25.1283872180504,0 55.4128642903327,25.1276363094542,0 55.4126874589678,25.1275051819951,0 55.4096643176932,25.125263310076,0 55.409610652616,25.1252235125407,0 55.4095122663319,25.1242157618125,0 55.4113393698166,25.1221445768316,0 55.41048128880449,25.1216320644562,0 55.4098465017888,25.1222629235916,0 55.4096773047847,25.12239450439341,0 55.4090823561741,25.1225792107926,0 55.4075495939051,25.1224260329677,0 55.40721940139449,25.1223930326464,0 55.4068892078198,25.1223600315896,0 55.4063233359894,25.1223034741225,0 55.4060983061139,25.1222175148368,0 55.4056219586014,25.1220355527438,0 55.4050965750733,25.1216911830316,0 55.4040182794793,25.120984388531,0 55.40347913694999,25.1206309877394,0 55.4032095668475,25.1204542865995,0 55.4029098938765,25.1202578529406,0 55.4024484622445,25.1199159555612,0 55.3997538045893,25.1179106383982,0 55.3991811882824,25.1174844922724,0 55.39836360140931,25.1168760283206,0 55.3975920831719,25.116301839197,0 55.3973879893689,25.1161499444299,0 55.3970627320927,25.1158592182103,0 55.3967832547785,25.1156094117755,0 55.3963092073573,25.1151856867966,0 55.395598142974,25.114550096993,0 55.3952610132604,25.1142487469675,0 55.39419687847879,25.1154381653303,0 55.396262147862,25.1169677163018,0 55.4002659146777,25.1199473857981,0 55.4002820672604,25.1200958661829,0 55.4000696873544,25.1203310681105,0 55.3990770962424,25.1214303024032,0 55.3993890689209,25.1216637999998,0 55.4003805628442,25.1205639295411,0 55.4006070464227,25.1203131071771,0 55.4007413157518,25.1203011702612,0 55.4037566618812,25.1225450502171,0 55.4052193811013,25.1236282139547,0 55.4057902278608,25.127045517961,0 55.40451611945529,25.1287421250157,0 55.40515651903169,25.1292195078661,0 55.4070954272547,25.1277433088925,0 55.4109996541604,25.1281792657904,0 55.41292900454749,25.1293370970414,0 55.416654342509,25.1320969113279,0 55.4166543623542,25.1320969293713,0
					</coordinates>
				</LinearRing>
			</outerBoundaryIs>
		</Polygon>
	</Placemark>
</Document>
</kml>

使用插件

使用时相对于leaflet-gpx简单些,直接通过new L.KML(kml)创建即可

import 'leaflet-kml';

const loadKml = () => {
  fetch('./kml/2.kml')
    .then(response => response.text())
    .then(e => {
      // 解析XML格式的字符串。
      // 创建了一个DOMParser对象,然后使用该对象的parseFromString方法将输入的字符串(变量e)解析为一个XML文档对象
      // 这里的'text/xml'参数表示输入字符串的MIME类型是XML
      const parser = new DOMParser();
      const kml = parser.parseFromString(e, 'text/xml');

      const track = new L.KML(kml);
      map.addLayer(track);

      const bounds = track.getBounds();
      map.fitBounds(bounds);
    });
};

在这里插入图片描述

插件源码分析

在上面使用的过程当中,是拿到kml文件的内容并且转成了XML形式的DOM结构。

源码位置:node_modules\leaflet-kml\L.KML.js

这里先对整个进行初始化操作,然后执行addKML方法。在这里面核心在parseKML方法。

L.KML = L.FeatureGroup.extend({

  initialize: function (kml) {
    // 初始化对应需要用的变量  kml信息、layers图层组
    this._kml = kml;
    this._layers = {};

    if (kml) {
      this.addKML(kml);
    }
  },
  addKML: function (xml) {
    var layers = L.KML.parseKML(xml);
    // 给每一个layer都抛出addlayer事件,并且在最后抛出loaded事件
    for (var i = 0; i < layers.length; i++) {
      this.fire('addlayer', {
        layer: layers[i]
      });
      this.addLayer(layers[i]);
    }
    this.latLngs = L.KML.getLatLngs(xml);
    this.fire('loaded');
  }
});

核心方法parseKML。

  • 记录所有style样式信息
  • 找Folder标签,递归解析(每一个Folder标签就相当于是一个Layer)
  • 找Placemark标签,递归解析
  • 找GroundOverlay标签,递归解析
  • 最终把所有的kml数据组装成一个layers数组返回。再抛出loaded事件。

L.Util.extend(L.KML, {
  parseKML: function (xml) {
    // 找Style标签,把样式信息记录下来
    var style = this.parseStyles(xml);
    this.parseStyleMap(xml, style);
    var el = xml.getElementsByTagName('Folder');
    var layers = [], l;
    for (var i = 0; i < el.length; i++) {
      if (!this._check_folder(el[i])) {
        continue;
      }
      l = this.parseFolder(el[i], style);
      if (l) {
        layers.push(l);
      }
    }
    el = xml.getElementsByTagName('Placemark');
    for (var j = 0; j < el.length; j++) {
      if (!this._check_folder(el[j])) {
        continue;
      }
      l = this.parsePlacemark(el[j], xml, style);
      if (l) {
        layers.push(l);
      }
    }
    el = xml.getElementsByTagName('GroundOverlay');
    for (var k = 0; k < el.length; k++) {
      l = this.parseGroundOverlay(el[k]);
      if (l) {
        layers.push(l);
      }
    }
    return layers;
  }
});
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Modify_QmQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值