Repository files navigation

Cluster

CircleCIGo ReportGo Doc

The origin of this library is in GoCluster

Guys did amazing job

This fork is better implementation with few additional features.

- Method to obtain expansion zoom
- Google maps example
- Better (refactored) implementation

Please look at godocs here.

Cluster is a very fast Golang library for geospatial point clustering.

This image is demo of JS library, this will work faster, because Golang is faster :-)

clusters2

The cluster use hierarchical greedy clustering approach. The same approach used by Dave Leaver with his fantastic Leaflet.markercluster plugin.

So this approach is extremely fast, the only drawback is that all clustered points are stored in memory

This library is deeply inspired by MapBox's superclaster JS library and blog post: https://www.mapbox.com/blog/supercluster/

Very easy to use:

// 1.Convert slice of your objects to slice of GeoPoint (interface) objectsgeoPoints:=make([]GeoPoint, len(points))
fori:=rangepoints {
geoPoints[i] =points[i]
}
// 2.Create new cluster (this will build index)c, _:=cluster.New(geoPoints, cluster.WithinZoom(0, 21))
// 3.Get tour tile with mercator coordinate projections to display directly on the mapresult:=c.GetTile(0,0,0)
// or get all clusters for zoom 10results:=c.AllClusters(10) 

Library has only one dependency, it's KD-tree geospatial index

All ids of Point that you have as result are the index of initial array of Geopoint, so you could get you point by this index.

Init cluster index

To init index, you need to prepare your data. All your points should implement GeoPoint interface:

typeGeoPointinterface {
GetCoordinates() GeoCoordinates
}
typeGeoCoordinatesstruct {
Lngfloat64Latfloat64
}

You could tweak the Cluster:

parameterdefault valuedescription
MinZoom0Minimum zoom level at which clusters are generated
MaxZoom16Minimum zoom level at which clusters are generated
PointSize40Cluster radius, in pixels
TileSize512Tile extent. Radius is calculated relative to this value
NodeSize64NodeSize is size of the KD-tree node. Higher means faster indexing but slower search, and vise versa.

Available option functions:

WithPointSize(sizeint) OptionWithTileSize(sizeint) OptionWithinZoom(min, maxint) OptionWithNodeSize(sizeint) Option// creating new clusterNew(points []GeoPoint, opts...Option) (*Cluster, error)

Search point in boundary box

To search all points inside the box, that are limited by the box, formed by north-west point and east-south points. You need to provide Z index as well.

northWest:=simplePoint{71.36718750000001, -83.79204408779539}
southEast:=simplePoint{-71.01562500000001, 83.7539108491127}
zoom:=2varresults:= c.GetClusters(northWest, southEast, zoom)

Returns the array of 'ClusterPoint' for zoom level. Each point has following coordinates:

  • X coordinate of returned object is Longitude and
  • Y coordinate of returned object is Latitude
  • if the object is cluster of points (NumPoints > 1), the ID is generated started from ClusterIdxSeed (ID>ClusterIdxSeed)
  • if the object represents only one point, it's id is the index of initial GeoPoints array

Search points for tile

OSM and Google maps uses tiles system to optimize map loading. So you could get all points for the tile with tileX, tileY and zoom:

c:=NewCluster(geoPoints)
tileX:=0tileY:=1zoom:=4results:=c.GetTile(tileX, tileY, zoom)

In this case all coordinates are returned in pixels for that tile. If you want to return objects with Lat, Lng, use GetTileWithLatLng method.

TODO: Benchmarks

About

Go fast geopoints clustering

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Cluster

CircleCIGo ReportGo Doc

The origin of this library is in GoCluster

Guys did amazing job

This fork is better implementation with few additional features.

- Method to obtain expansion zoom
- Google maps example
- Better (refactored) implementation

Please look at godocs here.

Cluster is a very fast Golang library for geospatial point clustering.

This image is demo of JS library, this will work faster, because Golang is faster :-)

clusters2

The cluster use hierarchical greedy clustering approach. The same approach used by Dave Leaver with his fantastic Leaflet.markercluster plugin.

So this approach is extremely fast, the only drawback is that all clustered points are stored in memory

This library is deeply inspired by MapBox's superclaster JS library and blog post: https://www.mapbox.com/blog/supercluster/

Very easy to use:

// 1.Convert slice of your objects to slice of GeoPoint (interface) objectsgeoPoints:=make([]GeoPoint, len(points))
fori:=rangepoints {
geoPoints[i] =points[i]
}
// 2.Create new cluster (this will build index)c, _:=cluster.New(geoPoints, cluster.WithinZoom(0, 21))
// 3.Get tour tile with mercator coordinate projections to display directly on the mapresult:=c.GetTile(0,0,0)
// or get all clusters for zoom 10results:=c.AllClusters(10) 

Library has only one dependency, it's KD-tree geospatial index

All ids of Point that you have as result are the index of initial array of Geopoint, so you could get you point by this index.

Init cluster index

To init index, you need to prepare your data. All your points should implement GeoPoint interface:

typeGeoPointinterface {
GetCoordinates() GeoCoordinates
}
typeGeoCoordinatesstruct {
Lngfloat64Latfloat64
}

You could tweak the Cluster:

parameterdefault valuedescription
MinZoom0Minimum zoom level at which clusters are generated
MaxZoom16Minimum zoom level at which clusters are generated
PointSize40Cluster radius, in pixels
TileSize512Tile extent. Radius is calculated relative to this value
NodeSize64NodeSize is size of the KD-tree node. Higher means faster indexing but slower search, and vise versa.

Available option functions:

WithPointSize(sizeint) OptionWithTileSize(sizeint) OptionWithinZoom(min, maxint) OptionWithNodeSize(sizeint) Option// creating new clusterNew(points []GeoPoint, opts...Option) (*Cluster, error)

Search point in boundary box

To search all points inside the box, that are limited by the box, formed by north-west point and east-south points. You need to provide Z index as well.

northWest:=simplePoint{71.36718750000001, -83.79204408779539}
southEast:=simplePoint{-71.01562500000001, 83.7539108491127}
zoom:=2varresults:= c.GetClusters(northWest, southEast, zoom)

Returns the array of 'ClusterPoint' for zoom level. Each point has following coordinates:

  • X coordinate of returned object is Longitude and
  • Y coordinate of returned object is Latitude
  • if the object is cluster of points (NumPoints > 1), the ID is generated started from ClusterIdxSeed (ID>ClusterIdxSeed)
  • if the object represents only one point, it's id is the index of initial GeoPoints array

Search points for tile

OSM and Google maps uses tiles system to optimize map loading. So you could get all points for the tile with tileX, tileY and zoom:

c:=NewCluster(geoPoints)
tileX:=0tileY:=1zoom:=4results:=c.GetTile(tileX, tileY, zoom)

In this case all coordinates are returned in pixels for that tile. If you want to return objects with Lat, Lng, use GetTileWithLatLng method.

TODO: Benchmarks

About

Go fast geopoints clustering

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Cluster

CircleCIGo ReportGo Doc

The origin of this library is in GoCluster

Guys did amazing job

This fork is better implementation with few additional features.

- Method to obtain expansion zoom
- Google maps example
- Better (refactored) implementation

Please look at godocs here.

Cluster is a very fast Golang library for geospatial point clustering.

This image is demo of JS library, this will work faster, because Golang is faster :-)

clusters2

The cluster use hierarchical greedy clustering approach. The same approach used by Dave Leaver with his fantastic Leaflet.markercluster plugin.

So this approach is extremely fast, the only drawback is that all clustered points are stored in memory

This library is deeply inspired by MapBox's superclaster JS library and blog post: https://www.mapbox.com/blog/supercluster/

Very easy to use:

// 1.Convert slice of your objects to slice of GeoPoint (interface) objectsgeoPoints:=make([]GeoPoint, len(points))
fori:=rangepoints {
geoPoints[i] =points[i]
}
// 2.Create new cluster (this will build index)c, _:=cluster.New(geoPoints, cluster.WithinZoom(0, 21))
// 3.Get tour tile with mercator coordinate projections to display directly on the mapresult:=c.GetTile(0,0,0)
// or get all clusters for zoom 10results:=c.AllClusters(10) 

Library has only one dependency, it's KD-tree geospatial index

All ids of Point that you have as result are the index of initial array of Geopoint, so you could get you point by this index.

Init cluster index

To init index, you need to prepare your data. All your points should implement GeoPoint interface:

typeGeoPointinterface {
GetCoordinates() GeoCoordinates
}
typeGeoCoordinatesstruct {
Lngfloat64Latfloat64
}

You could tweak the Cluster:

parameterdefault valuedescription
MinZoom0Minimum zoom level at which clusters are generated
MaxZoom16Minimum zoom level at which clusters are generated
PointSize40Cluster radius, in pixels
TileSize512Tile extent. Radius is calculated relative to this value
NodeSize64NodeSize is size of the KD-tree node. Higher means faster indexing but slower search, and vise versa.

Available option functions:

WithPointSize(sizeint) OptionWithTileSize(sizeint) OptionWithinZoom(min, maxint) OptionWithNodeSize(sizeint) Option// creating new clusterNew(points []GeoPoint, opts...Option) (*Cluster, error)

Search point in boundary box

To search all points inside the box, that are limited by the box, formed by north-west point and east-south points. You need to provide Z index as well.

northWest:=simplePoint{71.36718750000001, -83.79204408779539}
southEast:=simplePoint{-71.01562500000001, 83.7539108491127}
zoom:=2varresults:= c.GetClusters(northWest, southEast, zoom)

Returns the array of 'ClusterPoint' for zoom level. Each point has following coordinates:

  • X coordinate of returned object is Longitude and
  • Y coordinate of returned object is Latitude
  • if the object is cluster of points (NumPoints > 1), the ID is generated started from ClusterIdxSeed (ID>ClusterIdxSeed)
  • if the object represents only one point, it's id is the index of initial GeoPoints array

Search points for tile

OSM and Google maps uses tiles system to optimize map loading. So you could get all points for the tile with tileX, tileY and zoom:

c:=NewCluster(geoPoints)
tileX:=0tileY:=1zoom:=4results:=c.GetTile(tileX, tileY, zoom)

In this case all coordinates are returned in pixels for that tile. If you want to return objects with Lat, Lng, use GetTileWithLatLng method.

TODO: Benchmarks

About

Go fast geopoints clustering

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Cluster

CircleCIGo ReportGo Doc

The origin of this library is in GoCluster

Guys did amazing job

This fork is better implementation with few additional features.

- Method to obtain expansion zoom
- Google maps example
- Better (refactored) implementation

Please look at godocs here.

Cluster is a very fast Golang library for geospatial point clustering.

This image is demo of JS library, this will work faster, because Golang is faster :-)

clusters2

The cluster use hierarchical greedy clustering approach. The same approach used by Dave Leaver with his fantastic Leaflet.markercluster plugin.

So this approach is extremely fast, the only drawback is that all clustered points are stored in memory

This library is deeply inspired by MapBox's superclaster JS library and blog post: https://www.mapbox.com/blog/supercluster/

Very easy to use:

// 1.Convert slice of your objects to slice of GeoPoint (interface) objectsgeoPoints:=make([]GeoPoint, len(points))
fori:=rangepoints {
geoPoints[i] =points[i]
}
// 2.Create new cluster (this will build index)c, _:=cluster.New(geoPoints, cluster.WithinZoom(0, 21))
// 3.Get tour tile with mercator coordinate projections to display directly on the mapresult:=c.GetTile(0,0,0)
// or get all clusters for zoom 10results:=c.AllClusters(10) 

Library has only one dependency, it's KD-tree geospatial index

All ids of Point that you have as result are the index of initial array of Geopoint, so you could get you point by this index.

Init cluster index

To init index, you need to prepare your data. All your points should implement GeoPoint interface:

typeGeoPointinterface {
GetCoordinates() GeoCoordinates
}
typeGeoCoordinatesstruct {
Lngfloat64Latfloat64
}

You could tweak the Cluster:

parameterdefault valuedescription
MinZoom0Minimum zoom level at which clusters are generated
MaxZoom16Minimum zoom level at which clusters are generated
PointSize40Cluster radius, in pixels
TileSize512Tile extent. Radius is calculated relative to this value
NodeSize64NodeSize is size of the KD-tree node. Higher means faster indexing but slower search, and vise versa.

Available option functions:

WithPointSize(sizeint) OptionWithTileSize(sizeint) OptionWithinZoom(min, maxint) OptionWithNodeSize(sizeint) Option// creating new clusterNew(points []GeoPoint, opts...Option) (*Cluster, error)

Search point in boundary box

To search all points inside the box, that are limited by the box, formed by north-west point and east-south points. You need to provide Z index as well.

northWest:=simplePoint{71.36718750000001, -83.79204408779539}
southEast:=simplePoint{-71.01562500000001, 83.7539108491127}
zoom:=2varresults:= c.GetClusters(northWest, southEast, zoom)

Returns the array of 'ClusterPoint' for zoom level. Each point has following coordinates:

  • X coordinate of returned object is Longitude and
  • Y coordinate of returned object is Latitude
  • if the object is cluster of points (NumPoints > 1), the ID is generated started from ClusterIdxSeed (ID>ClusterIdxSeed)
  • if the object represents only one point, it's id is the index of initial GeoPoints array

Search points for tile

OSM and Google maps uses tiles system to optimize map loading. So you could get all points for the tile with tileX, tileY and zoom:

c:=NewCluster(geoPoints)
tileX:=0tileY:=1zoom:=4results:=c.GetTile(tileX, tileY, zoom)

In this case all coordinates are returned in pixels for that tile. If you want to return objects with Lat, Lng, use GetTileWithLatLng method.

TODO: Benchmarks

About

Go fast geopoints clustering

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Cluster

CircleCIGo ReportGo Doc

The origin of this library is in GoCluster

Guys did amazing job

This fork is better implementation with few additional features.

- Method to obtain expansion zoom
- Google maps example
- Better (refactored) implementation

Please look at godocs here.

Cluster is a very fast Golang library for geospatial point clustering.

This image is demo of JS library, this will work faster, because Golang is faster :-)

clusters2

The cluster use hierarchical greedy clustering approach. The same approach used by Dave Leaver with his fantastic Leaflet.markercluster plugin.

So this approach is extremely fast, the only drawback is that all clustered points are stored in memory

This library is deeply inspired by MapBox's superclaster JS library and blog post: https://www.mapbox.com/blog/supercluster/

Very easy to use:

// 1.Convert slice of your objects to slice of GeoPoint (interface) objectsgeoPoints:=make([]GeoPoint, len(points))
fori:=rangepoints {
geoPoints[i] =points[i]
}
// 2.Create new cluster (this will build index)c, _:=cluster.New(geoPoints, cluster.WithinZoom(0, 21))
// 3.Get tour tile with mercator coordinate projections to display directly on the mapresult:=c.GetTile(0,0,0)
// or get all clusters for zoom 10results:=c.AllClusters(10) 

Library has only one dependency, it's KD-tree geospatial index

All ids of Point that you have as result are the index of initial array of Geopoint, so you could get you point by this index.

Init cluster index

To init index, you need to prepare your data. All your points should implement GeoPoint interface:

typeGeoPointinterface {
GetCoordinates() GeoCoordinates
}
typeGeoCoordinatesstruct {
Lngfloat64Latfloat64
}

You could tweak the Cluster:

parameterdefault valuedescription
MinZoom0Minimum zoom level at which clusters are generated
MaxZoom16Minimum zoom level at which clusters are generated
PointSize40Cluster radius, in pixels
TileSize512Tile extent. Radius is calculated relative to this value
NodeSize64NodeSize is size of the KD-tree node. Higher means faster indexing but slower search, and vise versa.

Available option functions:

WithPointSize(sizeint) OptionWithTileSize(sizeint) OptionWithinZoom(min, maxint) OptionWithNodeSize(sizeint) Option// creating new clusterNew(points []GeoPoint, opts...Option) (*Cluster, error)

Search point in boundary box

To search all points inside the box, that are limited by the box, formed by north-west point and east-south points. You need to provide Z index as well.

northWest:=simplePoint{71.36718750000001, -83.79204408779539}
southEast:=simplePoint{-71.01562500000001, 83.7539108491127}
zoom:=2varresults:= c.GetClusters(northWest, southEast, zoom)

Returns the array of 'ClusterPoint' for zoom level. Each point has following coordinates:

  • X coordinate of returned object is Longitude and
  • Y coordinate of returned object is Latitude
  • if the object is cluster of points (NumPoints > 1), the ID is generated started from ClusterIdxSeed (ID>ClusterIdxSeed)
  • if the object represents only one point, it's id is the index of initial GeoPoints array

Search points for tile

OSM and Google maps uses tiles system to optimize map loading. So you could get all points for the tile with tileX, tileY and zoom:

c:=NewCluster(geoPoints)
tileX:=0tileY:=1zoom:=4results:=c.GetTile(tileX, tileY, zoom)

In this case all coordinates are returned in pixels for that tile. If you want to return objects with Lat, Lng, use GetTileWithLatLng method.

TODO: Benchmarks

About

Go fast geopoints clustering

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Cluster

CircleCIGo ReportGo Doc

The origin of this library is in GoCluster

Guys did amazing job

This fork is better implementation with few additional features.

- Method to obtain expansion zoom
- Google maps example
- Better (refactored) implementation

Please look at godocs here.

Cluster is a very fast Golang library for geospatial point clustering.

This image is demo of JS library, this will work faster, because Golang is faster :-)

clusters2

The cluster use hierarchical greedy clustering approach. The same approach used by Dave Leaver with his fantastic Leaflet.markercluster plugin.

So this approach is extremely fast, the only drawback is that all clustered points are stored in memory

This library is deeply inspired by MapBox's superclaster JS library and blog post: https://www.mapbox.com/blog/supercluster/

Very easy to use:

// 1.Convert slice of your objects to slice of GeoPoint (interface) objectsgeoPoints:=make([]GeoPoint, len(points))
fori:=rangepoints {
geoPoints[i] =points[i]
}
// 2.Create new cluster (this will build index)c, _:=cluster.New(geoPoints, cluster.WithinZoom(0, 21))
// 3.Get tour tile with mercator coordinate projections to display directly on the mapresult:=c.GetTile(0,0,0)
// or get all clusters for zoom 10results:=c.AllClusters(10) 

Library has only one dependency, it's KD-tree geospatial index

All ids of Point that you have as result are the index of initial array of Geopoint, so you could get you point by this index.

Init cluster index

To init index, you need to prepare your data. All your points should implement GeoPoint interface:

typeGeoPointinterface {
GetCoordinates() GeoCoordinates
}
typeGeoCoordinatesstruct {
Lngfloat64Latfloat64
}

You could tweak the Cluster:

parameterdefault valuedescription
MinZoom0Minimum zoom level at which clusters are generated
MaxZoom16Minimum zoom level at which clusters are generated
PointSize40Cluster radius, in pixels
TileSize512Tile extent. Radius is calculated relative to this value
NodeSize64NodeSize is size of the KD-tree node. Higher means faster indexing but slower search, and vise versa.

Available option functions:

WithPointSize(sizeint) OptionWithTileSize(sizeint) OptionWithinZoom(min, maxint) OptionWithNodeSize(sizeint) Option// creating new clusterNew(points []GeoPoint, opts...Option) (*Cluster, error)

Search point in boundary box

To search all points inside the box, that are limited by the box, formed by north-west point and east-south points. You need to provide Z index as well.

northWest:=simplePoint{71.36718750000001, -83.79204408779539}
southEast:=simplePoint{-71.01562500000001, 83.7539108491127}
zoom:=2varresults:= c.GetClusters(northWest, southEast, zoom)

Returns the array of 'ClusterPoint' for zoom level. Each point has following coordinates:

  • X coordinate of returned object is Longitude and
  • Y coordinate of returned object is Latitude
  • if the object is cluster of points (NumPoints > 1), the ID is generated started from ClusterIdxSeed (ID>ClusterIdxSeed)
  • if the object represents only one point, it's id is the index of initial GeoPoints array

Search points for tile

OSM and Google maps uses tiles system to optimize map loading. So you could get all points for the tile with tileX, tileY and zoom:

c:=NewCluster(geoPoints)
tileX:=0tileY:=1zoom:=4results:=c.GetTile(tileX, tileY, zoom)

In this case all coordinates are returned in pixels for that tile. If you want to return objects with Lat, Lng, use GetTileWithLatLng method.

TODO: Benchmarks

About

Go fast geopoints clustering

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Cluster

CircleCIGo ReportGo Doc

The origin of this library is in GoCluster

Guys did amazing job

This fork is better implementation with few additional features.

- Method to obtain expansion zoom
- Google maps example
- Better (refactored) implementation

Please look at godocs here.

Cluster is a very fast Golang library for geospatial point clustering.

This image is demo of JS library, this will work faster, because Golang is faster :-)

clusters2

The cluster use hierarchical greedy clustering approach. The same approach used by Dave Leaver with his fantastic Leaflet.markercluster plugin.

So this approach is extremely fast, the only drawback is that all clustered points are stored in memory

This library is deeply inspired by MapBox's superclaster JS library and blog post: https://www.mapbox.com/blog/supercluster/

Very easy to use:

// 1.Convert slice of your objects to slice of GeoPoint (interface) objectsgeoPoints:=make([]GeoPoint, len(points))
fori:=rangepoints {
geoPoints[i] =points[i]
}
// 2.Create new cluster (this will build index)c, _:=cluster.New(geoPoints, cluster.WithinZoom(0, 21))
// 3.Get tour tile with mercator coordinate projections to display directly on the mapresult:=c.GetTile(0,0,0)
// or get all clusters for zoom 10results:=c.AllClusters(10) 

Library has only one dependency, it's KD-tree geospatial index

All ids of Point that you have as result are the index of initial array of Geopoint, so you could get you point by this index.

Init cluster index

To init index, you need to prepare your data. All your points should implement GeoPoint interface:

typeGeoPointinterface {
GetCoordinates() GeoCoordinates
}
typeGeoCoordinatesstruct {
Lngfloat64Latfloat64
}

You could tweak the Cluster:

parameterdefault valuedescription
MinZoom0Minimum zoom level at which clusters are generated
MaxZoom16Minimum zoom level at which clusters are generated
PointSize40Cluster radius, in pixels
TileSize512Tile extent. Radius is calculated relative to this value
NodeSize64NodeSize is size of the KD-tree node. Higher means faster indexing but slower search, and vise versa.

Available option functions:

WithPointSize(sizeint) OptionWithTileSize(sizeint) OptionWithinZoom(min, maxint) OptionWithNodeSize(sizeint) Option// creating new clusterNew(points []GeoPoint, opts...Option) (*Cluster, error)

Search point in boundary box

To search all points inside the box, that are limited by the box, formed by north-west point and east-south points. You need to provide Z index as well.

northWest:=simplePoint{71.36718750000001, -83.79204408779539}
southEast:=simplePoint{-71.01562500000001, 83.7539108491127}
zoom:=2varresults:= c.GetClusters(northWest, southEast, zoom)

Returns the array of 'ClusterPoint' for zoom level. Each point has following coordinates:

  • X coordinate of returned object is Longitude and
  • Y coordinate of returned object is Latitude
  • if the object is cluster of points (NumPoints > 1), the ID is generated started from ClusterIdxSeed (ID>ClusterIdxSeed)
  • if the object represents only one point, it's id is the index of initial GeoPoints array

Search points for tile

OSM and Google maps uses tiles system to optimize map loading. So you could get all points for the tile with tileX, tileY and zoom:

c:=NewCluster(geoPoints)
tileX:=0tileY:=1zoom:=4results:=c.GetTile(tileX, tileY, zoom)

In this case all coordinates are returned in pixels for that tile. If you want to return objects with Lat, Lng, use GetTileWithLatLng method.

TODO: Benchmarks

About

Go fast geopoints clustering

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Cluster

CircleCIGo ReportGo Doc

The origin of this library is in GoCluster

Guys did amazing job

This fork is better implementation with few additional features.

- Method to obtain expansion zoom
- Google maps example
- Better (refactored) implementation

Please look at godocs here.

Cluster is a very fast Golang library for geospatial point clustering.

This image is demo of JS library, this will work faster, because Golang is faster :-)

clusters2

The cluster use hierarchical greedy clustering approach. The same approach used by Dave Leaver with his fantastic Leaflet.markercluster plugin.

So this approach is extremely fast, the only drawback is that all clustered points are stored in memory

This library is deeply inspired by MapBox's superclaster JS library and blog post: https://www.mapbox.com/blog/supercluster/

Very easy to use:

// 1.Convert slice of your objects to slice of GeoPoint (interface) objectsgeoPoints:=make([]GeoPoint, len(points))
fori:=rangepoints {
geoPoints[i] =points[i]
}
// 2.Create new cluster (this will build index)c, _:=cluster.New(geoPoints, cluster.WithinZoom(0, 21))
// 3.Get tour tile with mercator coordinate projections to display directly on the mapresult:=c.GetTile(0,0,0)
// or get all clusters for zoom 10results:=c.AllClusters(10) 

Library has only one dependency, it's KD-tree geospatial index

All ids of Point that you have as result are the index of initial array of Geopoint, so you could get you point by this index.

Init cluster index

To init index, you need to prepare your data. All your points should implement GeoPoint interface:

typeGeoPointinterface {
GetCoordinates() GeoCoordinates
}
typeGeoCoordinatesstruct {
Lngfloat64Latfloat64
}

You could tweak the Cluster:

parameterdefault valuedescription
MinZoom0Minimum zoom level at which clusters are generated
MaxZoom16Minimum zoom level at which clusters are generated
PointSize40Cluster radius, in pixels
TileSize512Tile extent. Radius is calculated relative to this value
NodeSize64NodeSize is size of the KD-tree node. Higher means faster indexing but slower search, and vise versa.

Available option functions:

WithPointSize(sizeint) OptionWithTileSize(sizeint) OptionWithinZoom(min, maxint) OptionWithNodeSize(sizeint) Option// creating new clusterNew(points []GeoPoint, opts...Option) (*Cluster, error)

Search point in boundary box

To search all points inside the box, that are limited by the box, formed by north-west point and east-south points. You need to provide Z index as well.

northWest:=simplePoint{71.36718750000001, -83.79204408779539}
southEast:=simplePoint{-71.01562500000001, 83.7539108491127}
zoom:=2varresults:= c.GetClusters(northWest, southEast, zoom)

Returns the array of 'ClusterPoint' for zoom level. Each point has following coordinates:

  • X coordinate of returned object is Longitude and
  • Y coordinate of returned object is Latitude
  • if the object is cluster of points (NumPoints > 1), the ID is generated started from ClusterIdxSeed (ID>ClusterIdxSeed)
  • if the object represents only one point, it's id is the index of initial GeoPoints array

Search points for tile

OSM and Google maps uses tiles system to optimize map loading. So you could get all points for the tile with tileX, tileY and zoom:

c:=NewCluster(geoPoints)
tileX:=0tileY:=1zoom:=4results:=c.GetTile(tileX, tileY, zoom)

In this case all coordinates are returned in pixels for that tile. If you want to return objects with Lat, Lng, use GetTileWithLatLng method.

TODO: Benchmarks

About

Go fast geopoints clustering

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages