Skip to content

Instantly share code, notes, and snippets.

@VioletVivirand
Last active August 11, 2016 05:14
Show Gist options
  • Save VioletVivirand/ca78fdf18a52d60bcc921fd612f38ab9 to your computer and use it in GitHub Desktop.
Save VioletVivirand/ca78fdf18a52d60bcc921fd612f38ab9 to your computer and use it in GitHub Desktop.
license: gpl-3.0

Built with Leaflet, blockbuilder.org

Data Source

Please download it from Open Data.Kaohsiung. However, the unit of the data is based on TWD97, we need to convert them to something like WGS84 then things would get easier.

If you wanna build your own script to convert, here are some references:

Or you gonna use somebody else's script to achievve the goal, here are something you can use:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<style>
#mapid {
width: 960px;
height: 720px;
}
svg {
position: relative;
}
path {
/*fill: #000;*/
fill-opacity: .0;
stroke: brown;
stroke-width: 1.5px;
}
/*path:hover {
fill: brown;
fill-opacity: .7;
}*/
.tooltip {
position: absolute;
z-index: 10;
font-size: 8pt;
border: black;
border-style: solid;
border-width: 1px;
}
</style>
</head>
<body>
<div id="mapid"></div>
<script>
var mymap = L.map('mapid', {
center: [22.73, 120.42],
zoom: 10
// dragging: false,
// scrollWheelZoom: 'center',
// doubleClickZoom: 'center',
// boxZoom: false
}); // center 跟 zoom 這兩個 option 也可以改寫成 .setView([23.6, 121], 8);
// 讀取 OpenStreetMap 的 Map Tile
L.tileLayer("http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: '<a href="http://openstreetmap.org">OpenStreetMap</a>'
}).addTo(mymap);
// 在 .leaflet-objects-pane --> .leaflet-overlay-pane 裡面新增 Element
var svg = d3.select(mymap.getPanes().overlayPane).append("svg"),
g = svg.append("g").attr("class", "leaflet-zoom-hide");
// 讀取、綁定資料
d3.json("kh_topojson.json", function(error, kh) {
if (error) throw error;
// 把 GeoJSON 轉換成 SVG
var transform = d3.geo.transform({
point: projectPoint
}),
path = d3.geo.path().projection(transform);
// 用 Data Join 的方式加入 Path
// 這時候還沒有實際去畫出 Path,等下才要加入 `.attr("d", path);`,這邊先等等
var feature = g.selectAll("path")
.data(topojson.feature(kh, kh.objects.kh_bike_geojson_edited).features)
.enter().append("path");
// Smooth Path
// Ref: http://bl.ocks.org/shimizu/1d32c3dfc6cec3b337f2
var interpolate = d3.svg.line()
.x(function(d) {
return d[0]
}).y(function(d) {
return d[1]
}).interpolate("basis");
var smoothPath = function(pstr) {
var sp = path(pstr).replace(/M|Z/, "").split("L").map(function(d) {
return d.split(",")
});
return interpolate(sp);
};
// 加入 Tooltip
var tooltip = d3.select("body")
.data(topojson.feature(kh, kh.objects.kh_bike_geojson_edited).features)
.append("div")
.attr("class", "tooltip")
.style("visibility", "hidden");
// 每次圖片一有什麼動作(移動、縮放、等等等),就要重新繪圖
mymap.on("viewreset", reset);
reset();
// Reposition the SVG to cover the features.
function reset() {
// SVG 的尺寸很難界定,因為使用者會對 SVG 放大縮小,所以指定一個固定的尺寸並不切實際
// 要用 D3 的 Path bounds 來幫忙(https://github.com/mbostock/d3/wiki/Geo-Paths#wiki-path_bounds)
var bounds = path.bounds(topojson.feature(kh, kh.objects.kh_bike_geojson_edited)),
topLeft = bounds[0],
bottomRight = bounds[1];
svg.attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");
g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
feature.attr("d", function(d) {
return smoothPath(d);
})
.on("mouseover", function() {
return tooltip.style("visibility", "visible");
})
.on("mousemove", function(d) {
return tooltip.style("top", (d3.event.pageY - 10) + "px").style("left", (d3.event.pageX + 10) + "px").text(d.properties.name);
})
.on("mouseout", function() {
return tooltip.style("visibility", "hidden");
});
}
// Use Leaflet to implement a D3 geometric transformation.
// 因為 D3 用來處理 Projection 的系統跟 Leaflet 不一樣,所以用個函式來轉換
// 官方說法:D3 and Leaflet use different APIs for rendering shapes and projecting points.
function projectPoint(x, y) {
var point = mymap.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
});
</script>
</body>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment