kandi background
Explore Kits

QuadTree | quadTree implementation | Map library

 by   roma98 Java Version: Current License: No License

 by   roma98 Java Version: Current License: No License

Download this library from

kandi X-RAY | QuadTree Summary

QuadTree is a Java library typically used in Geo, Map applications. QuadTree has no bugs, it has no vulnerabilities and it has low support. However QuadTree build file is not available. You can download it from GitHub.
QuadTree implementation, and application for handling cab traffic.
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • QuadTree has a low active ecosystem.
  • It has 40 star(s) with 1 fork(s). There are 1 watchers for this library.
  • It had no major release in the last 12 months.
  • QuadTree has no issues reported. There are no pull requests.
  • It has a neutral sentiment in the developer community.
  • The latest version of QuadTree is current.
QuadTree Support
Best in #Map
Average in #Map
QuadTree Support
Best in #Map
Average in #Map

quality kandi Quality

  • QuadTree has no bugs reported.
QuadTree Quality
Best in #Map
Average in #Map
QuadTree Quality
Best in #Map
Average in #Map

securitySecurity

  • QuadTree has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
QuadTree Security
Best in #Map
Average in #Map
QuadTree Security
Best in #Map
Average in #Map

license License

  • QuadTree does not have a standard license declared.
  • Check the repository for any license declaration and review the terms closely.
  • Without a license, all rights are reserved, and you cannot use the library in your applications.
QuadTree License
Best in #Map
Average in #Map
QuadTree License
Best in #Map
Average in #Map

buildReuse

  • QuadTree releases are not available. You will need to build from source code and install.
  • QuadTree has no build file. You will be need to create the build yourself to build the component from source.
QuadTree Reuse
Best in #Map
Average in #Map
QuadTree Reuse
Best in #Map
Average in #Map
Top functions reviewed by kandi - BETA

kandi's functional review helps you automatically verify the functionalities of the libraries and avoid rework.
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample Here

Get all kandi verified functions for this library.

Get all kandi verified functions for this library.

QuadTree Key Features

quadTree implementation

How to free all memory blocks of a picture using quadree structure with different cases?

copy iconCopydownload iconDownload
void freeMemory(image *myImage) {
    if (myImage != NULL && *myImage != NULL) {
        int sonSize = sizeof((*myImage)->son) / sizeof((*myImage)->son[0]);
        while (sonSize) freeMemory(&(*myImage)->son[--sonSize]);
        free(*myImage);
        *myImage = NULL;
    }
}
puts("\nfreeMemory\n");
image white = Build_white();
image black = Build_black();
puts("before");
normalDisplay(black);
puts("");
puts("after");
freeMemory(&black);
normalDisplay(black);
puts("");
puts("before");
normalDisplay(white);
puts("\nafter");
freeMemory(&white);
normalDisplay(white);
puts("");
void freeMemory(image *myImage) {
    if (myImage != NULL && *myImage != NULL) {
        int sonSize = sizeof((*myImage)->son) / sizeof((*myImage)->son[0]);
        while (sonSize) freeMemory(&(*myImage)->son[--sonSize]);
        free(*myImage);
        *myImage = NULL;
    }
}
puts("\nfreeMemory\n");
image white = Build_white();
image black = Build_black();
puts("before");
normalDisplay(black);
puts("");
puts("after");
freeMemory(&black);
normalDisplay(black);
puts("");
puts("before");
normalDisplay(white);
puts("\nafter");
freeMemory(&white);
normalDisplay(white);
puts("");

Rendering imageData to new canvas

copy iconCopydownload iconDownload
// Draw a white background (you effectively need it otherwise your default
// pixels will be black).
new Path.Rectangle({
    rectangle: view.bounds,
    fillColor: 'white'
});

// Draw a black rectangle covering most of the canvas.
new Path.Rectangle({
    rectangle: view.bounds.scale(0.9),
    fillColor: 'black'
});

// Make sure that the scene is drawn into the canvas.
view.update();

// Get the canvas image data.
const { width, height } = view.element;
const imageData = view.context.getImageData(0, 0, width, height);

// Loop over each pixel and store all the different colors to check that this works.
const colors = new Set();
const length = imageData.data.length;
for (let i = 0; i < length; i += 4) {
    const [r, g, b, a] = imageData.data.slice(i, i + 4);
    const color = JSON.stringify({ r, g, b, a });
    colors.add(color);
}
console.log('colors', [...colors]);

How to display composed quadtrees using C language?

copy iconCopydownload iconDownload
typedef struct block_image image;
void normalDisplay(image *t) {
    if (t == NULL) {
       printf("W"); 
    } else if (t->allBlack) {
       printf("B");
    } else {
       printf("+");
       normalDisplay(t->son[0]);  // upper left
       normalDisplay(t->son[1]);  // upper right
       normalDisplay(t->son[2]);  // lower left
       normalDisplay(t->son[3]);  // lower right
   }
}

How can I use d3 force to space out overlapping points on a map

copy iconCopydownload iconDownload
.each(d=>[d.x,d.y] = projection([d.longitude, d.latitude]))
simulation.nodes(forceids.data())
let margin = { top: 0, right: 0, bottom: 10, left: 0 },
            width = 1000 - margin.left - margin.right,
            height = 800 - margin.top - margin.bottom;

        let projection = geoAlbersUsaTerritories.geoAlbersUsaTerritories()
            .scale(width)
            .translate([width / 2, height / 2.2]);

        const path = d3.geoPath()
            .projection(projection);

        var simulation = d3.forceSimulation()
            .force('charge', d3.forceManyBody().strength(-160))
            .stop()

        let eventX,
            eventY

        const formatDate2 = d3.timeFormat("%m-%Y")

        const svg = d3.select("#content")
            .append("svg")
            .attr('id', 'map')
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)

        const map = svg.append('g')
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .attr('class', 'map')

        const landmass = map.append('g').attr('class', 'land')

        const places = map.append('g').attr('id', 'places')

        svg.append('ellipse').classed("radius", true).attr('id', 'locate')

        d3.json("https://unpkg.com/us-atlas@3.0.0/states-10m.json").then(function (usa) {

            landmass.selectAll('path')
                .data(topojson.feature(usa, usa.objects.nation).features)
                .enter().append("path")
                .attr("d", path)
                .attr("class", "outline")
                .attr('fill', '#ccc')
                .attr("stroke", "#999")

            landmass.append("path")
                .datum(topojson.mesh(usa, usa.objects.states, function (a, b) { return a !== b; }))
                .attr("class", "mesh")
                .attr("d", path)
                .attr('fill', 'none')
                .attr('stroke', 'white')
        });

        const data = [
            {
                "id": 3448,
                "name": "General Edward Lawrence Logan Intl",
                "city": "Boston",
                "faa": "BOS",
                "latitude": 42.364347,
                "longitude": -71.005181
            },
            {
                "id": 3453,
                "name": "Metropolitan Oakland Intl",
                "city": "Oakland",
                "faa": "OAK",
                "latitude": 37.721278,
                "longitude": -122.220722
            },
            {
                "id": 3454,
                "name": "Eppley Afld",
                "city": "Omaha",
                "faa": "OMA",
                "latitude": 41.303167,
                "longitude": -95.894069
            },
            {
                "id": 3457,
                "name": "Wichita Mid Continent",
                "city": "Wichita",
                "faa": "ICT",
                "latitude": 37.649944,
                "longitude": -97.433056
            },
            {
                "id": 3458,
                "name": "Kansas City Intl",
                "city": "Kansas City",
                "faa": "MCI",
                "latitude": 39.297606,
                "longitude": -94.713905
            },
            {
                "id": 3459,
                "name": "Dane Co Rgnl Truax Fld",
                "city": "Madison",
                "faa": "MSN",
                "latitude": 43.139858,
                "longitude": -89.337514
            },
            {
                "id": 3462,
                "name": "Phoenix Sky Harbor Intl",
                "city": "Phoenix",
                "faa": "PHX",
                "latitude": 33.434278,
                "longitude": -112.011583
            },
            {
                "id": 3467,
                "name": "Spokane Intl",
                "city": "Spokane",
                "faa": "GEG",
                "latitude": 47.619861,
                "longitude": -117.533833
            },
            {
                "id": 3469,
                "name": "San Francisco Intl",
                "city": "San Francisco",
                "faa": "SFO",
                "latitude": 37.618972,
                "longitude": -122.374889
            },
            {
                "id": 3472,
                "name": "Gainesville Rgnl",
                "city": "Gainesville",
                "faa": "GNV",
                "latitude": 29.690056,
                "longitude": -82.271778
            },
            {
                "id": 3473,
                "name": "Memphis Intl",
                "city": "Memphis",
                "faa": "MEM",
                "latitude": 35.042417,
                "longitude": -89.976667
            },
            {
                "id": 3484,
                "name": "Los Angeles Intl",
                "city": "Los Angeles",
                "faa": "LAX",
                "latitude": 33.942536,
                "longitude": -118.408075
            },
            {
                "id": 3486,
                "name": "Cleveland Hopkins Intl",
                "city": "Cleveland",
                "faa": "CLE",
                "latitude": 41.411689,
                "longitude": -81.849794
            },            
            {
                "id": 3494,
                "name": "Newark Liberty Intl",
                "city": "Newark",
                "faa": "EWR",
                "latitude": 40.6925,
                "longitude": -74.168667
            },
            {
                "id": 3502,
                "name": "Dallas Love Fld",
                "city": "Dallas",
                "faa": "DAL",
                "latitude": 32.847111,
                "longitude": -96.851778
            },
            {
                "id": 3550,
                "name": "George Bush Intercontinental",
                "city": "Houston",
                "faa": "IAH",
                "latitude": 29.984433,
                "longitude": -95.341442
            },
            {
                "id": 3559,
                "name": "El Paso Intl",
                "city": "El Paso",
                "faa": "ELP",
                "latitude": 31.80725,
                "longitude": -106.377583
            },
            {
                "id": 3566,
                "name": "William P Hobby",
                "city": "Houston",
                "faa": "HOU",
                "latitude": 29.645419,
                "longitude": -95.278889
            },
            {
                "id": 3570,
                "name": "Pittsburgh Intl",
                "city": "Pittsburgh",
                "faa": "PIT",
                "latitude": 40.491467,
                "longitude": -80.232872
            },
            {
                "id": 3576,
                "name": "Miami Intl",
                "city": "Miami",
                "faa": "MIA",
                "latitude": 25.79325,
                "longitude": -80.290556
            },
            {
                "id": 3582,
                "name": "Long Beach",
                "city": "Long Beach",
                "faa": "LGB",
                "latitude": 33.817722,
                "longitude": -118.151611
            },
            {
                "id": 3585,
                "name": "Indianapolis Intl",
                "city": "Indianapolis",
                "faa": "IND",
                "latitude": 39.717331,
                "longitude": -86.294383
            },
            {
                "id": 3589,
                "name": "Westchester Co",
                "city": "White Plains",
                "faa": "HPN",
                "latitude": 41.066959,
                "longitude": -73.707575
            },
            {
                "id": 3697,
                "name": "La Guardia",
                "city": "New York",
                "faa": "LGA",
                "latitude": 40.777245,
                "longitude": -73.872608
            },
            {
                "id": 3747,
                "name": "Chicago Midway Intl",
                "city": "Chicago",
                "faa": "MDW",
                "latitude": 41.785972,
                "longitude": -87.752417
            },
            {
                "id": 3797,
                "name": "John F Kennedy Intl",
                "city": "New York",
                "faa": "JFK",
                "latitude": 40.639751,
                "longitude": -73.778925
            },
            {
                "id": 3830,
                "name": "Chicago Ohare Intl",
                "city": "Chicago",
                "faa": "ORD",
                "latitude": 41.978603,
                "longitude": -87.904842
            }
        ]

        d3.selectAll('.close').on('click', function () {
            d3.selectAll('.popup').remove()
        })
        data.forEach(function (d) {
            d.latitude = +d.latitude;
            d.longitude = +d.longitude;
        })
        d3.selectAll('.location').remove()

        let locations = places.selectAll(".location")
            .data(data);

        locations.enter()
            .append("circle")
            .attr('id', d => 'n' + d.id)
            .attr("class", 'location')
            .attr('cx', d => projection([d.longitude, d.latitude])[0])
            .attr('cy', d => projection([d.longitude, d.latitude])[1])
            .each(d=>[d.x,d.y] = projection([d.longitude, d.latitude]))
            .attr("r", 5)
            .attr('fill', 'green')
            .style('stroke', '#fff')
            .style('stroke-width', .5)
            .style("opacity", .75)
            .on('click', function (event, d) {
                simulation.stop()

                var isSelectedCode = d.detention_facility_code
                var isSelectedName = d.name
                var whichclass = d3.select(this).attr("class").split(' ');
                let activeIndex = whichclass.indexOf('active')

                var sel = d3.select(this);
                sel.raise();

                let latlng = [d.longitude, d.latitude]
                $('#clickedFacility').text(d.name)
                $('#slider').removeClass('hide')
                showRadius(latlng, far)

            })
            .on("mouseover", function (event, d) {
                var sel = d3.select(this);
                sel.raise();

                let tooltip_str = d.name
                tooltip.html(tooltip_str)
                    .style("visibility", "visible");
            })
            .on("mousemove", function (event, d) {
                tooltip.style("top", event.pageY - (tooltip.node().clientHeight + 5) + "px")
                    .style("left", event.pageX - (tooltip.node().clientWidth / 2.0) + "px");
            })
            .on("mouseout", function (event, d) {
                var sel = d3.select(this);
                sel.lower();
                tooltip.style("visibility", "hidden");
            })

        locations
            .transition()
            .duration(100)
            .attr("class", d => "location " + d.name.replace(/[\s]/g, '') + ' ' + d.type_detailed.replace(/\s+|[,\/]/g, "") + ' closed' + d.is_closed)
            .attr("r", 5)
            .attr('fill', 'green')

        locations.exit()
            .remove();

        const tooltip = d3.select("body").append("div")
            .attr("class", "tooltip");

        var info = svg.append("div")
            .attr("class", "info");

        const quadtree = d3.quadtree()
            .x(d => +d.longitude)
            .y(d => +d.latitude)
            .addAll(data);

        let miles = 30

        let far = (1 / 60) * miles; // in degrees

        function showRadius(evt, far) {
        
            // Reset //
             svg.selectAll('circle')
                 .attr('cx', d => d.x = projection([d.longitude, d.latitude])[0])
                 .attr('cy', d => d.y = projection([d.longitude, d.latitude])[1])       
                 .attr('fill', 'green')
            /////
        

            d3.select('ellipse.radius').remove();

            let radiusCircle = map.append("ellipse").classed("radius", true).attr('id', 'locate')

            let xy = projection.invert(evt)
            console.log('xy', xy)

            let xyObject = { "longitude": evt[0], "latitude": evt[1] }
            radiusLng = evt[0] + far
            radiusLat = evt[1] + far
            radiusLngLat = [+radiusLng, +radiusLat]
            radiusPoint = projection(radiusLngLat)
            console.log('radiusPoint', radiusPoint)

            radiusX = Math.abs(evt[1] + far)
            radiusY = Math.abs(evt[0] + far)

            radiusToPoint = projection([radiusY, radiusX][0])

            d3.select('ellipse.radius').classed('hide', false)
            d3.select('ellipse.radius').classed('show', true)

            let radiusprojx = projection(evt)[0]
            let radiusprojxN = projection(evt)[0] - eventX
            let radiusprojy = projection(evt)[1]
            let radiusprojyN = projection(evt)[1] - eventY

            radiusCircle
                .attr('cx', d => (projection(evt)[0]))
                .attr('cy', d => (projection(evt)[1]))
                .attr('rx', 20)
                .attr('ry', 20)

            let hits = [];
            quadtree.visit(nearest(xyObject, far, hits))

            for (i = 0; i < hits.length; i++) {
                let line = turf.lineString([[evt[1], evt[0]], [hits[i].latitude, hits[i].longitude]]);
                let length = turf.length(line, { units: 'miles' });
                hits[i].distance = +length.toFixed(2) + ' miles';
            }
            hits.sort(function (a, b) { return d3.ascending(a.distance, b.distance) })

            let locationsInRadius = hits.map(a => a.id);
            //console.log('locationsInRadius', locationsInRadius)

            d3.selectAll('.location').attr('fill', 'green')
            locationsInRadius.forEach(function (d, i) {
                d3.select('#n' + d).attr('fill', 'blue')
            })

            let total_count = hits.length

            $("#hitnumber").text(total_count + " airports within 30 miles")

            d3.selectAll('.list-item').remove()

            let listItem = d3.selectAll('#hits').selectAll('text')
                .data(hits)
                .attr('padding-left', '20px')
                .enter().append('div').attr('class', 'list-item')
                .html(d => d.name + "<br/>Lat: " + d.latitude + "<br/>Lng: " + d.longitude + "<br/>Distance: " + d.distance)

            if (hits.length == 1) {
            } else {
                const hitids = []

                for (i = 0; i < hits.length; i++) {
                    hitids.push('#n' + hits[i].id)
                }
                let idstoget = hitids.toString()

                let forceids = d3.selectAll(idstoget)

                simulation.force('x', d3.forceX().strength(0.1).x(radiusPoint[0]))
                simulation.force('y', d3.forceY().strength(0.1).y(radiusPoint[1]))

                // simulation.force('center', d3.forceCenter(radiusPoint[0], radiusPoint[1]))

                simulation.alpha(1).restart()

                simulation.nodes(forceids.data())
                    .on('tick', ticked)

                function ticked() {
                    update(forceids)
                }

                function update(forceids) {

                    forceids
                        .attr('cx', function (d) { return d.x })
                        .attr('cy', function (d) { return d.y })
                }
            }
        }

        function nearest(node, radius, hits) {
            if (!hits) hits = [];
            var r = radius,
                nx1 = node.longitude - r,
                nx2 = node.longitude + r,
                ny1 = node.latitude - r,
                ny2 = node.latitude + r;

            return function (quad, x1, y1, x2, y2) {
                if (quad.data && (quad.data !== node)) {
                    var x = node.longitude - quad.data.longitude,
                        y = node.latitude - quad.data.latitude,
                        l = Math.sqrt(x * x + y * y),
                        r = radius;
                    if (l < r) {
                        hits.push(quad.data)
                    } else {
                    }
                }
                return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
            }
        }
.tooltip {
            position: absolute;
            padding: 15px;
            font: 12px sans-serif;
            background: #fff;
            color: #000;
            border: 0px;
            pointer-events: none;
            opacity: 0.8;
            visibility: hidden;
            -moz-box-shadow: 0 0 15px #aaa;
            -webkit-box-shadow: 0 0 15px #aaa;
            box-shadow: 0 0 15px #aaa;
        }

        .close {
            float: right;
            margin-top: 1 px;
        }

        .multiple-choice {
            padding: 3px 0;
        }

        .radius {
            fill-opacity: 0.15;
            stroke: #333;
            stroke-dasharray: 4 2;
            z-index: 1000;
            fill: #bff4ff;
            display: none;
        }

        #panel {
            position: absolute;
            left: 1030px;
            top: 0px;
            width: 300px;
            padding-top: 50px;
        }

        .list-item {
            padding: 10px;
        }

        label {
            margin: 0;
            padding: 0;
            font-family: Arial, Helvetica, sans-serif;
        }

        #hitnumber {
            font-family: Arial, Helvetica, sans-serif;
            padding-left: 10px;
        }

        .hide {
            display: none;
        }
<script src="https://cdn.jsdelivr.net/npm/d3-quadtree@3"></script>
    <script src="https://d3js.org/d3.v6.min.js"></script>
    <script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="https://unpkg.com/topojson-client@3"></script>
    <script src="https://unpkg.com/geo-albers-usa-territories@0.1.0/dist/geo-albers-usa-territories.js"></script>
    <div id="content"></div>
    <div id="panel">
        <div id="list">
            <div id="hitnumber"></div>
            <pre><div id="hits"></div></pre>
        </div>
    </div>
    <div id="chart-title"></div>
.each(d=>[d.x,d.y] = projection([d.longitude, d.latitude]))
simulation.nodes(forceids.data())
let margin = { top: 0, right: 0, bottom: 10, left: 0 },
            width = 1000 - margin.left - margin.right,
            height = 800 - margin.top - margin.bottom;

        let projection = geoAlbersUsaTerritories.geoAlbersUsaTerritories()
            .scale(width)
            .translate([width / 2, height / 2.2]);

        const path = d3.geoPath()
            .projection(projection);

        var simulation = d3.forceSimulation()
            .force('charge', d3.forceManyBody().strength(-160))
            .stop()

        let eventX,
            eventY

        const formatDate2 = d3.timeFormat("%m-%Y")

        const svg = d3.select("#content")
            .append("svg")
            .attr('id', 'map')
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)

        const map = svg.append('g')
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .attr('class', 'map')

        const landmass = map.append('g').attr('class', 'land')

        const places = map.append('g').attr('id', 'places')

        svg.append('ellipse').classed("radius", true).attr('id', 'locate')

        d3.json("https://unpkg.com/us-atlas@3.0.0/states-10m.json").then(function (usa) {

            landmass.selectAll('path')
                .data(topojson.feature(usa, usa.objects.nation).features)
                .enter().append("path")
                .attr("d", path)
                .attr("class", "outline")
                .attr('fill', '#ccc')
                .attr("stroke", "#999")

            landmass.append("path")
                .datum(topojson.mesh(usa, usa.objects.states, function (a, b) { return a !== b; }))
                .attr("class", "mesh")
                .attr("d", path)
                .attr('fill', 'none')
                .attr('stroke', 'white')
        });

        const data = [
            {
                "id": 3448,
                "name": "General Edward Lawrence Logan Intl",
                "city": "Boston",
                "faa": "BOS",
                "latitude": 42.364347,
                "longitude": -71.005181
            },
            {
                "id": 3453,
                "name": "Metropolitan Oakland Intl",
                "city": "Oakland",
                "faa": "OAK",
                "latitude": 37.721278,
                "longitude": -122.220722
            },
            {
                "id": 3454,
                "name": "Eppley Afld",
                "city": "Omaha",
                "faa": "OMA",
                "latitude": 41.303167,
                "longitude": -95.894069
            },
            {
                "id": 3457,
                "name": "Wichita Mid Continent",
                "city": "Wichita",
                "faa": "ICT",
                "latitude": 37.649944,
                "longitude": -97.433056
            },
            {
                "id": 3458,
                "name": "Kansas City Intl",
                "city": "Kansas City",
                "faa": "MCI",
                "latitude": 39.297606,
                "longitude": -94.713905
            },
            {
                "id": 3459,
                "name": "Dane Co Rgnl Truax Fld",
                "city": "Madison",
                "faa": "MSN",
                "latitude": 43.139858,
                "longitude": -89.337514
            },
            {
                "id": 3462,
                "name": "Phoenix Sky Harbor Intl",
                "city": "Phoenix",
                "faa": "PHX",
                "latitude": 33.434278,
                "longitude": -112.011583
            },
            {
                "id": 3467,
                "name": "Spokane Intl",
                "city": "Spokane",
                "faa": "GEG",
                "latitude": 47.619861,
                "longitude": -117.533833
            },
            {
                "id": 3469,
                "name": "San Francisco Intl",
                "city": "San Francisco",
                "faa": "SFO",
                "latitude": 37.618972,
                "longitude": -122.374889
            },
            {
                "id": 3472,
                "name": "Gainesville Rgnl",
                "city": "Gainesville",
                "faa": "GNV",
                "latitude": 29.690056,
                "longitude": -82.271778
            },
            {
                "id": 3473,
                "name": "Memphis Intl",
                "city": "Memphis",
                "faa": "MEM",
                "latitude": 35.042417,
                "longitude": -89.976667
            },
            {
                "id": 3484,
                "name": "Los Angeles Intl",
                "city": "Los Angeles",
                "faa": "LAX",
                "latitude": 33.942536,
                "longitude": -118.408075
            },
            {
                "id": 3486,
                "name": "Cleveland Hopkins Intl",
                "city": "Cleveland",
                "faa": "CLE",
                "latitude": 41.411689,
                "longitude": -81.849794
            },            
            {
                "id": 3494,
                "name": "Newark Liberty Intl",
                "city": "Newark",
                "faa": "EWR",
                "latitude": 40.6925,
                "longitude": -74.168667
            },
            {
                "id": 3502,
                "name": "Dallas Love Fld",
                "city": "Dallas",
                "faa": "DAL",
                "latitude": 32.847111,
                "longitude": -96.851778
            },
            {
                "id": 3550,
                "name": "George Bush Intercontinental",
                "city": "Houston",
                "faa": "IAH",
                "latitude": 29.984433,
                "longitude": -95.341442
            },
            {
                "id": 3559,
                "name": "El Paso Intl",
                "city": "El Paso",
                "faa": "ELP",
                "latitude": 31.80725,
                "longitude": -106.377583
            },
            {
                "id": 3566,
                "name": "William P Hobby",
                "city": "Houston",
                "faa": "HOU",
                "latitude": 29.645419,
                "longitude": -95.278889
            },
            {
                "id": 3570,
                "name": "Pittsburgh Intl",
                "city": "Pittsburgh",
                "faa": "PIT",
                "latitude": 40.491467,
                "longitude": -80.232872
            },
            {
                "id": 3576,
                "name": "Miami Intl",
                "city": "Miami",
                "faa": "MIA",
                "latitude": 25.79325,
                "longitude": -80.290556
            },
            {
                "id": 3582,
                "name": "Long Beach",
                "city": "Long Beach",
                "faa": "LGB",
                "latitude": 33.817722,
                "longitude": -118.151611
            },
            {
                "id": 3585,
                "name": "Indianapolis Intl",
                "city": "Indianapolis",
                "faa": "IND",
                "latitude": 39.717331,
                "longitude": -86.294383
            },
            {
                "id": 3589,
                "name": "Westchester Co",
                "city": "White Plains",
                "faa": "HPN",
                "latitude": 41.066959,
                "longitude": -73.707575
            },
            {
                "id": 3697,
                "name": "La Guardia",
                "city": "New York",
                "faa": "LGA",
                "latitude": 40.777245,
                "longitude": -73.872608
            },
            {
                "id": 3747,
                "name": "Chicago Midway Intl",
                "city": "Chicago",
                "faa": "MDW",
                "latitude": 41.785972,
                "longitude": -87.752417
            },
            {
                "id": 3797,
                "name": "John F Kennedy Intl",
                "city": "New York",
                "faa": "JFK",
                "latitude": 40.639751,
                "longitude": -73.778925
            },
            {
                "id": 3830,
                "name": "Chicago Ohare Intl",
                "city": "Chicago",
                "faa": "ORD",
                "latitude": 41.978603,
                "longitude": -87.904842
            }
        ]

        d3.selectAll('.close').on('click', function () {
            d3.selectAll('.popup').remove()
        })
        data.forEach(function (d) {
            d.latitude = +d.latitude;
            d.longitude = +d.longitude;
        })
        d3.selectAll('.location').remove()

        let locations = places.selectAll(".location")
            .data(data);

        locations.enter()
            .append("circle")
            .attr('id', d => 'n' + d.id)
            .attr("class", 'location')
            .attr('cx', d => projection([d.longitude, d.latitude])[0])
            .attr('cy', d => projection([d.longitude, d.latitude])[1])
            .each(d=>[d.x,d.y] = projection([d.longitude, d.latitude]))
            .attr("r", 5)
            .attr('fill', 'green')
            .style('stroke', '#fff')
            .style('stroke-width', .5)
            .style("opacity", .75)
            .on('click', function (event, d) {
                simulation.stop()

                var isSelectedCode = d.detention_facility_code
                var isSelectedName = d.name
                var whichclass = d3.select(this).attr("class").split(' ');
                let activeIndex = whichclass.indexOf('active')

                var sel = d3.select(this);
                sel.raise();

                let latlng = [d.longitude, d.latitude]
                $('#clickedFacility').text(d.name)
                $('#slider').removeClass('hide')
                showRadius(latlng, far)

            })
            .on("mouseover", function (event, d) {
                var sel = d3.select(this);
                sel.raise();

                let tooltip_str = d.name
                tooltip.html(tooltip_str)
                    .style("visibility", "visible");
            })
            .on("mousemove", function (event, d) {
                tooltip.style("top", event.pageY - (tooltip.node().clientHeight + 5) + "px")
                    .style("left", event.pageX - (tooltip.node().clientWidth / 2.0) + "px");
            })
            .on("mouseout", function (event, d) {
                var sel = d3.select(this);
                sel.lower();
                tooltip.style("visibility", "hidden");
            })

        locations
            .transition()
            .duration(100)
            .attr("class", d => "location " + d.name.replace(/[\s]/g, '') + ' ' + d.type_detailed.replace(/\s+|[,\/]/g, "") + ' closed' + d.is_closed)
            .attr("r", 5)
            .attr('fill', 'green')

        locations.exit()
            .remove();

        const tooltip = d3.select("body").append("div")
            .attr("class", "tooltip");

        var info = svg.append("div")
            .attr("class", "info");

        const quadtree = d3.quadtree()
            .x(d => +d.longitude)
            .y(d => +d.latitude)
            .addAll(data);

        let miles = 30

        let far = (1 / 60) * miles; // in degrees

        function showRadius(evt, far) {
        
            // Reset //
             svg.selectAll('circle')
                 .attr('cx', d => d.x = projection([d.longitude, d.latitude])[0])
                 .attr('cy', d => d.y = projection([d.longitude, d.latitude])[1])       
                 .attr('fill', 'green')
            /////
        

            d3.select('ellipse.radius').remove();

            let radiusCircle = map.append("ellipse").classed("radius", true).attr('id', 'locate')

            let xy = projection.invert(evt)
            console.log('xy', xy)

            let xyObject = { "longitude": evt[0], "latitude": evt[1] }
            radiusLng = evt[0] + far
            radiusLat = evt[1] + far
            radiusLngLat = [+radiusLng, +radiusLat]
            radiusPoint = projection(radiusLngLat)
            console.log('radiusPoint', radiusPoint)

            radiusX = Math.abs(evt[1] + far)
            radiusY = Math.abs(evt[0] + far)

            radiusToPoint = projection([radiusY, radiusX][0])

            d3.select('ellipse.radius').classed('hide', false)
            d3.select('ellipse.radius').classed('show', true)

            let radiusprojx = projection(evt)[0]
            let radiusprojxN = projection(evt)[0] - eventX
            let radiusprojy = projection(evt)[1]
            let radiusprojyN = projection(evt)[1] - eventY

            radiusCircle
                .attr('cx', d => (projection(evt)[0]))
                .attr('cy', d => (projection(evt)[1]))
                .attr('rx', 20)
                .attr('ry', 20)

            let hits = [];
            quadtree.visit(nearest(xyObject, far, hits))

            for (i = 0; i < hits.length; i++) {
                let line = turf.lineString([[evt[1], evt[0]], [hits[i].latitude, hits[i].longitude]]);
                let length = turf.length(line, { units: 'miles' });
                hits[i].distance = +length.toFixed(2) + ' miles';
            }
            hits.sort(function (a, b) { return d3.ascending(a.distance, b.distance) })

            let locationsInRadius = hits.map(a => a.id);
            //console.log('locationsInRadius', locationsInRadius)

            d3.selectAll('.location').attr('fill', 'green')
            locationsInRadius.forEach(function (d, i) {
                d3.select('#n' + d).attr('fill', 'blue')
            })

            let total_count = hits.length

            $("#hitnumber").text(total_count + " airports within 30 miles")

            d3.selectAll('.list-item').remove()

            let listItem = d3.selectAll('#hits').selectAll('text')
                .data(hits)
                .attr('padding-left', '20px')
                .enter().append('div').attr('class', 'list-item')
                .html(d => d.name + "<br/>Lat: " + d.latitude + "<br/>Lng: " + d.longitude + "<br/>Distance: " + d.distance)

            if (hits.length == 1) {
            } else {
                const hitids = []

                for (i = 0; i < hits.length; i++) {
                    hitids.push('#n' + hits[i].id)
                }
                let idstoget = hitids.toString()

                let forceids = d3.selectAll(idstoget)

                simulation.force('x', d3.forceX().strength(0.1).x(radiusPoint[0]))
                simulation.force('y', d3.forceY().strength(0.1).y(radiusPoint[1]))

                // simulation.force('center', d3.forceCenter(radiusPoint[0], radiusPoint[1]))

                simulation.alpha(1).restart()

                simulation.nodes(forceids.data())
                    .on('tick', ticked)

                function ticked() {
                    update(forceids)
                }

                function update(forceids) {

                    forceids
                        .attr('cx', function (d) { return d.x })
                        .attr('cy', function (d) { return d.y })
                }
            }
        }

        function nearest(node, radius, hits) {
            if (!hits) hits = [];
            var r = radius,
                nx1 = node.longitude - r,
                nx2 = node.longitude + r,
                ny1 = node.latitude - r,
                ny2 = node.latitude + r;

            return function (quad, x1, y1, x2, y2) {
                if (quad.data && (quad.data !== node)) {
                    var x = node.longitude - quad.data.longitude,
                        y = node.latitude - quad.data.latitude,
                        l = Math.sqrt(x * x + y * y),
                        r = radius;
                    if (l < r) {
                        hits.push(quad.data)
                    } else {
                    }
                }
                return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
            }
        }
.tooltip {
            position: absolute;
            padding: 15px;
            font: 12px sans-serif;
            background: #fff;
            color: #000;
            border: 0px;
            pointer-events: none;
            opacity: 0.8;
            visibility: hidden;
            -moz-box-shadow: 0 0 15px #aaa;
            -webkit-box-shadow: 0 0 15px #aaa;
            box-shadow: 0 0 15px #aaa;
        }

        .close {
            float: right;
            margin-top: 1 px;
        }

        .multiple-choice {
            padding: 3px 0;
        }

        .radius {
            fill-opacity: 0.15;
            stroke: #333;
            stroke-dasharray: 4 2;
            z-index: 1000;
            fill: #bff4ff;
            display: none;
        }

        #panel {
            position: absolute;
            left: 1030px;
            top: 0px;
            width: 300px;
            padding-top: 50px;
        }

        .list-item {
            padding: 10px;
        }

        label {
            margin: 0;
            padding: 0;
            font-family: Arial, Helvetica, sans-serif;
        }

        #hitnumber {
            font-family: Arial, Helvetica, sans-serif;
            padding-left: 10px;
        }

        .hide {
            display: none;
        }
<script src="https://cdn.jsdelivr.net/npm/d3-quadtree@3"></script>
    <script src="https://d3js.org/d3.v6.min.js"></script>
    <script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="https://unpkg.com/topojson-client@3"></script>
    <script src="https://unpkg.com/geo-albers-usa-territories@0.1.0/dist/geo-albers-usa-territories.js"></script>
    <div id="content"></div>
    <div id="panel">
        <div id="list">
            <div id="hitnumber"></div>
            <pre><div id="hits"></div></pre>
        </div>
    </div>
    <div id="chart-title"></div>
.each(d=>[d.x,d.y] = projection([d.longitude, d.latitude]))
simulation.nodes(forceids.data())
let margin = { top: 0, right: 0, bottom: 10, left: 0 },
            width = 1000 - margin.left - margin.right,
            height = 800 - margin.top - margin.bottom;

        let projection = geoAlbersUsaTerritories.geoAlbersUsaTerritories()
            .scale(width)
            .translate([width / 2, height / 2.2]);

        const path = d3.geoPath()
            .projection(projection);

        var simulation = d3.forceSimulation()
            .force('charge', d3.forceManyBody().strength(-160))
            .stop()

        let eventX,
            eventY

        const formatDate2 = d3.timeFormat("%m-%Y")

        const svg = d3.select("#content")
            .append("svg")
            .attr('id', 'map')
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)

        const map = svg.append('g')
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .attr('class', 'map')

        const landmass = map.append('g').attr('class', 'land')

        const places = map.append('g').attr('id', 'places')

        svg.append('ellipse').classed("radius", true).attr('id', 'locate')

        d3.json("https://unpkg.com/us-atlas@3.0.0/states-10m.json").then(function (usa) {

            landmass.selectAll('path')
                .data(topojson.feature(usa, usa.objects.nation).features)
                .enter().append("path")
                .attr("d", path)
                .attr("class", "outline")
                .attr('fill', '#ccc')
                .attr("stroke", "#999")

            landmass.append("path")
                .datum(topojson.mesh(usa, usa.objects.states, function (a, b) { return a !== b; }))
                .attr("class", "mesh")
                .attr("d", path)
                .attr('fill', 'none')
                .attr('stroke', 'white')
        });

        const data = [
            {
                "id": 3448,
                "name": "General Edward Lawrence Logan Intl",
                "city": "Boston",
                "faa": "BOS",
                "latitude": 42.364347,
                "longitude": -71.005181
            },
            {
                "id": 3453,
                "name": "Metropolitan Oakland Intl",
                "city": "Oakland",
                "faa": "OAK",
                "latitude": 37.721278,
                "longitude": -122.220722
            },
            {
                "id": 3454,
                "name": "Eppley Afld",
                "city": "Omaha",
                "faa": "OMA",
                "latitude": 41.303167,
                "longitude": -95.894069
            },
            {
                "id": 3457,
                "name": "Wichita Mid Continent",
                "city": "Wichita",
                "faa": "ICT",
                "latitude": 37.649944,
                "longitude": -97.433056
            },
            {
                "id": 3458,
                "name": "Kansas City Intl",
                "city": "Kansas City",
                "faa": "MCI",
                "latitude": 39.297606,
                "longitude": -94.713905
            },
            {
                "id": 3459,
                "name": "Dane Co Rgnl Truax Fld",
                "city": "Madison",
                "faa": "MSN",
                "latitude": 43.139858,
                "longitude": -89.337514
            },
            {
                "id": 3462,
                "name": "Phoenix Sky Harbor Intl",
                "city": "Phoenix",
                "faa": "PHX",
                "latitude": 33.434278,
                "longitude": -112.011583
            },
            {
                "id": 3467,
                "name": "Spokane Intl",
                "city": "Spokane",
                "faa": "GEG",
                "latitude": 47.619861,
                "longitude": -117.533833
            },
            {
                "id": 3469,
                "name": "San Francisco Intl",
                "city": "San Francisco",
                "faa": "SFO",
                "latitude": 37.618972,
                "longitude": -122.374889
            },
            {
                "id": 3472,
                "name": "Gainesville Rgnl",
                "city": "Gainesville",
                "faa": "GNV",
                "latitude": 29.690056,
                "longitude": -82.271778
            },
            {
                "id": 3473,
                "name": "Memphis Intl",
                "city": "Memphis",
                "faa": "MEM",
                "latitude": 35.042417,
                "longitude": -89.976667
            },
            {
                "id": 3484,
                "name": "Los Angeles Intl",
                "city": "Los Angeles",
                "faa": "LAX",
                "latitude": 33.942536,
                "longitude": -118.408075
            },
            {
                "id": 3486,
                "name": "Cleveland Hopkins Intl",
                "city": "Cleveland",
                "faa": "CLE",
                "latitude": 41.411689,
                "longitude": -81.849794
            },            
            {
                "id": 3494,
                "name": "Newark Liberty Intl",
                "city": "Newark",
                "faa": "EWR",
                "latitude": 40.6925,
                "longitude": -74.168667
            },
            {
                "id": 3502,
                "name": "Dallas Love Fld",
                "city": "Dallas",
                "faa": "DAL",
                "latitude": 32.847111,
                "longitude": -96.851778
            },
            {
                "id": 3550,
                "name": "George Bush Intercontinental",
                "city": "Houston",
                "faa": "IAH",
                "latitude": 29.984433,
                "longitude": -95.341442
            },
            {
                "id": 3559,
                "name": "El Paso Intl",
                "city": "El Paso",
                "faa": "ELP",
                "latitude": 31.80725,
                "longitude": -106.377583
            },
            {
                "id": 3566,
                "name": "William P Hobby",
                "city": "Houston",
                "faa": "HOU",
                "latitude": 29.645419,
                "longitude": -95.278889
            },
            {
                "id": 3570,
                "name": "Pittsburgh Intl",
                "city": "Pittsburgh",
                "faa": "PIT",
                "latitude": 40.491467,
                "longitude": -80.232872
            },
            {
                "id": 3576,
                "name": "Miami Intl",
                "city": "Miami",
                "faa": "MIA",
                "latitude": 25.79325,
                "longitude": -80.290556
            },
            {
                "id": 3582,
                "name": "Long Beach",
                "city": "Long Beach",
                "faa": "LGB",
                "latitude": 33.817722,
                "longitude": -118.151611
            },
            {
                "id": 3585,
                "name": "Indianapolis Intl",
                "city": "Indianapolis",
                "faa": "IND",
                "latitude": 39.717331,
                "longitude": -86.294383
            },
            {
                "id": 3589,
                "name": "Westchester Co",
                "city": "White Plains",
                "faa": "HPN",
                "latitude": 41.066959,
                "longitude": -73.707575
            },
            {
                "id": 3697,
                "name": "La Guardia",
                "city": "New York",
                "faa": "LGA",
                "latitude": 40.777245,
                "longitude": -73.872608
            },
            {
                "id": 3747,
                "name": "Chicago Midway Intl",
                "city": "Chicago",
                "faa": "MDW",
                "latitude": 41.785972,
                "longitude": -87.752417
            },
            {
                "id": 3797,
                "name": "John F Kennedy Intl",
                "city": "New York",
                "faa": "JFK",
                "latitude": 40.639751,
                "longitude": -73.778925
            },
            {
                "id": 3830,
                "name": "Chicago Ohare Intl",
                "city": "Chicago",
                "faa": "ORD",
                "latitude": 41.978603,
                "longitude": -87.904842
            }
        ]

        d3.selectAll('.close').on('click', function () {
            d3.selectAll('.popup').remove()
        })
        data.forEach(function (d) {
            d.latitude = +d.latitude;
            d.longitude = +d.longitude;
        })
        d3.selectAll('.location').remove()

        let locations = places.selectAll(".location")
            .data(data);

        locations.enter()
            .append("circle")
            .attr('id', d => 'n' + d.id)
            .attr("class", 'location')
            .attr('cx', d => projection([d.longitude, d.latitude])[0])
            .attr('cy', d => projection([d.longitude, d.latitude])[1])
            .each(d=>[d.x,d.y] = projection([d.longitude, d.latitude]))
            .attr("r", 5)
            .attr('fill', 'green')
            .style('stroke', '#fff')
            .style('stroke-width', .5)
            .style("opacity", .75)
            .on('click', function (event, d) {
                simulation.stop()

                var isSelectedCode = d.detention_facility_code
                var isSelectedName = d.name
                var whichclass = d3.select(this).attr("class").split(' ');
                let activeIndex = whichclass.indexOf('active')

                var sel = d3.select(this);
                sel.raise();

                let latlng = [d.longitude, d.latitude]
                $('#clickedFacility').text(d.name)
                $('#slider').removeClass('hide')
                showRadius(latlng, far)

            })
            .on("mouseover", function (event, d) {
                var sel = d3.select(this);
                sel.raise();

                let tooltip_str = d.name
                tooltip.html(tooltip_str)
                    .style("visibility", "visible");
            })
            .on("mousemove", function (event, d) {
                tooltip.style("top", event.pageY - (tooltip.node().clientHeight + 5) + "px")
                    .style("left", event.pageX - (tooltip.node().clientWidth / 2.0) + "px");
            })
            .on("mouseout", function (event, d) {
                var sel = d3.select(this);
                sel.lower();
                tooltip.style("visibility", "hidden");
            })

        locations
            .transition()
            .duration(100)
            .attr("class", d => "location " + d.name.replace(/[\s]/g, '') + ' ' + d.type_detailed.replace(/\s+|[,\/]/g, "") + ' closed' + d.is_closed)
            .attr("r", 5)
            .attr('fill', 'green')

        locations.exit()
            .remove();

        const tooltip = d3.select("body").append("div")
            .attr("class", "tooltip");

        var info = svg.append("div")
            .attr("class", "info");

        const quadtree = d3.quadtree()
            .x(d => +d.longitude)
            .y(d => +d.latitude)
            .addAll(data);

        let miles = 30

        let far = (1 / 60) * miles; // in degrees

        function showRadius(evt, far) {
        
            // Reset //
             svg.selectAll('circle')
                 .attr('cx', d => d.x = projection([d.longitude, d.latitude])[0])
                 .attr('cy', d => d.y = projection([d.longitude, d.latitude])[1])       
                 .attr('fill', 'green')
            /////
        

            d3.select('ellipse.radius').remove();

            let radiusCircle = map.append("ellipse").classed("radius", true).attr('id', 'locate')

            let xy = projection.invert(evt)
            console.log('xy', xy)

            let xyObject = { "longitude": evt[0], "latitude": evt[1] }
            radiusLng = evt[0] + far
            radiusLat = evt[1] + far
            radiusLngLat = [+radiusLng, +radiusLat]
            radiusPoint = projection(radiusLngLat)
            console.log('radiusPoint', radiusPoint)

            radiusX = Math.abs(evt[1] + far)
            radiusY = Math.abs(evt[0] + far)

            radiusToPoint = projection([radiusY, radiusX][0])

            d3.select('ellipse.radius').classed('hide', false)
            d3.select('ellipse.radius').classed('show', true)

            let radiusprojx = projection(evt)[0]
            let radiusprojxN = projection(evt)[0] - eventX
            let radiusprojy = projection(evt)[1]
            let radiusprojyN = projection(evt)[1] - eventY

            radiusCircle
                .attr('cx', d => (projection(evt)[0]))
                .attr('cy', d => (projection(evt)[1]))
                .attr('rx', 20)
                .attr('ry', 20)

            let hits = [];
            quadtree.visit(nearest(xyObject, far, hits))

            for (i = 0; i < hits.length; i++) {
                let line = turf.lineString([[evt[1], evt[0]], [hits[i].latitude, hits[i].longitude]]);
                let length = turf.length(line, { units: 'miles' });
                hits[i].distance = +length.toFixed(2) + ' miles';
            }
            hits.sort(function (a, b) { return d3.ascending(a.distance, b.distance) })

            let locationsInRadius = hits.map(a => a.id);
            //console.log('locationsInRadius', locationsInRadius)

            d3.selectAll('.location').attr('fill', 'green')
            locationsInRadius.forEach(function (d, i) {
                d3.select('#n' + d).attr('fill', 'blue')
            })

            let total_count = hits.length

            $("#hitnumber").text(total_count + " airports within 30 miles")

            d3.selectAll('.list-item').remove()

            let listItem = d3.selectAll('#hits').selectAll('text')
                .data(hits)
                .attr('padding-left', '20px')
                .enter().append('div').attr('class', 'list-item')
                .html(d => d.name + "<br/>Lat: " + d.latitude + "<br/>Lng: " + d.longitude + "<br/>Distance: " + d.distance)

            if (hits.length == 1) {
            } else {
                const hitids = []

                for (i = 0; i < hits.length; i++) {
                    hitids.push('#n' + hits[i].id)
                }
                let idstoget = hitids.toString()

                let forceids = d3.selectAll(idstoget)

                simulation.force('x', d3.forceX().strength(0.1).x(radiusPoint[0]))
                simulation.force('y', d3.forceY().strength(0.1).y(radiusPoint[1]))

                // simulation.force('center', d3.forceCenter(radiusPoint[0], radiusPoint[1]))

                simulation.alpha(1).restart()

                simulation.nodes(forceids.data())
                    .on('tick', ticked)

                function ticked() {
                    update(forceids)
                }

                function update(forceids) {

                    forceids
                        .attr('cx', function (d) { return d.x })
                        .attr('cy', function (d) { return d.y })
                }
            }
        }

        function nearest(node, radius, hits) {
            if (!hits) hits = [];
            var r = radius,
                nx1 = node.longitude - r,
                nx2 = node.longitude + r,
                ny1 = node.latitude - r,
                ny2 = node.latitude + r;

            return function (quad, x1, y1, x2, y2) {
                if (quad.data && (quad.data !== node)) {
                    var x = node.longitude - quad.data.longitude,
                        y = node.latitude - quad.data.latitude,
                        l = Math.sqrt(x * x + y * y),
                        r = radius;
                    if (l < r) {
                        hits.push(quad.data)
                    } else {
                    }
                }
                return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
            }
        }
.tooltip {
            position: absolute;
            padding: 15px;
            font: 12px sans-serif;
            background: #fff;
            color: #000;
            border: 0px;
            pointer-events: none;
            opacity: 0.8;
            visibility: hidden;
            -moz-box-shadow: 0 0 15px #aaa;
            -webkit-box-shadow: 0 0 15px #aaa;
            box-shadow: 0 0 15px #aaa;
        }

        .close {
            float: right;
            margin-top: 1 px;
        }

        .multiple-choice {
            padding: 3px 0;
        }

        .radius {
            fill-opacity: 0.15;
            stroke: #333;
            stroke-dasharray: 4 2;
            z-index: 1000;
            fill: #bff4ff;
            display: none;
        }

        #panel {
            position: absolute;
            left: 1030px;
            top: 0px;
            width: 300px;
            padding-top: 50px;
        }

        .list-item {
            padding: 10px;
        }

        label {
            margin: 0;
            padding: 0;
            font-family: Arial, Helvetica, sans-serif;
        }

        #hitnumber {
            font-family: Arial, Helvetica, sans-serif;
            padding-left: 10px;
        }

        .hide {
            display: none;
        }
<script src="https://cdn.jsdelivr.net/npm/d3-quadtree@3"></script>
    <script src="https://d3js.org/d3.v6.min.js"></script>
    <script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="https://unpkg.com/topojson-client@3"></script>
    <script src="https://unpkg.com/geo-albers-usa-territories@0.1.0/dist/geo-albers-usa-territories.js"></script>
    <div id="content"></div>
    <div id="panel">
        <div id="list">
            <div id="hitnumber"></div>
            <pre><div id="hits"></div></pre>
        </div>
    </div>
    <div id="chart-title"></div>
.each(d=>[d.x,d.y] = projection([d.longitude, d.latitude]))
simulation.nodes(forceids.data())
let margin = { top: 0, right: 0, bottom: 10, left: 0 },
            width = 1000 - margin.left - margin.right,
            height = 800 - margin.top - margin.bottom;

        let projection = geoAlbersUsaTerritories.geoAlbersUsaTerritories()
            .scale(width)
            .translate([width / 2, height / 2.2]);

        const path = d3.geoPath()
            .projection(projection);

        var simulation = d3.forceSimulation()
            .force('charge', d3.forceManyBody().strength(-160))
            .stop()

        let eventX,
            eventY

        const formatDate2 = d3.timeFormat("%m-%Y")

        const svg = d3.select("#content")
            .append("svg")
            .attr('id', 'map')
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)

        const map = svg.append('g')
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .attr('class', 'map')

        const landmass = map.append('g').attr('class', 'land')

        const places = map.append('g').attr('id', 'places')

        svg.append('ellipse').classed("radius", true).attr('id', 'locate')

        d3.json("https://unpkg.com/us-atlas@3.0.0/states-10m.json").then(function (usa) {

            landmass.selectAll('path')
                .data(topojson.feature(usa, usa.objects.nation).features)
                .enter().append("path")
                .attr("d", path)
                .attr("class", "outline")
                .attr('fill', '#ccc')
                .attr("stroke", "#999")

            landmass.append("path")
                .datum(topojson.mesh(usa, usa.objects.states, function (a, b) { return a !== b; }))
                .attr("class", "mesh")
                .attr("d", path)
                .attr('fill', 'none')
                .attr('stroke', 'white')
        });

        const data = [
            {
                "id": 3448,
                "name": "General Edward Lawrence Logan Intl",
                "city": "Boston",
                "faa": "BOS",
                "latitude": 42.364347,
                "longitude": -71.005181
            },
            {
                "id": 3453,
                "name": "Metropolitan Oakland Intl",
                "city": "Oakland",
                "faa": "OAK",
                "latitude": 37.721278,
                "longitude": -122.220722
            },
            {
                "id": 3454,
                "name": "Eppley Afld",
                "city": "Omaha",
                "faa": "OMA",
                "latitude": 41.303167,
                "longitude": -95.894069
            },
            {
                "id": 3457,
                "name": "Wichita Mid Continent",
                "city": "Wichita",
                "faa": "ICT",
                "latitude": 37.649944,
                "longitude": -97.433056
            },
            {
                "id": 3458,
                "name": "Kansas City Intl",
                "city": "Kansas City",
                "faa": "MCI",
                "latitude": 39.297606,
                "longitude": -94.713905
            },
            {
                "id": 3459,
                "name": "Dane Co Rgnl Truax Fld",
                "city": "Madison",
                "faa": "MSN",
                "latitude": 43.139858,
                "longitude": -89.337514
            },
            {
                "id": 3462,
                "name": "Phoenix Sky Harbor Intl",
                "city": "Phoenix",
                "faa": "PHX",
                "latitude": 33.434278,
                "longitude": -112.011583
            },
            {
                "id": 3467,
                "name": "Spokane Intl",
                "city": "Spokane",
                "faa": "GEG",
                "latitude": 47.619861,
                "longitude": -117.533833
            },
            {
                "id": 3469,
                "name": "San Francisco Intl",
                "city": "San Francisco",
                "faa": "SFO",
                "latitude": 37.618972,
                "longitude": -122.374889
            },
            {
                "id": 3472,
                "name": "Gainesville Rgnl",
                "city": "Gainesville",
                "faa": "GNV",
                "latitude": 29.690056,
                "longitude": -82.271778
            },
            {
                "id": 3473,
                "name": "Memphis Intl",
                "city": "Memphis",
                "faa": "MEM",
                "latitude": 35.042417,
                "longitude": -89.976667
            },
            {
                "id": 3484,
                "name": "Los Angeles Intl",
                "city": "Los Angeles",
                "faa": "LAX",
                "latitude": 33.942536,
                "longitude": -118.408075
            },
            {
                "id": 3486,
                "name": "Cleveland Hopkins Intl",
                "city": "Cleveland",
                "faa": "CLE",
                "latitude": 41.411689,
                "longitude": -81.849794
            },            
            {
                "id": 3494,
                "name": "Newark Liberty Intl",
                "city": "Newark",
                "faa": "EWR",
                "latitude": 40.6925,
                "longitude": -74.168667
            },
            {
                "id": 3502,
                "name": "Dallas Love Fld",
                "city": "Dallas",
                "faa": "DAL",
                "latitude": 32.847111,
                "longitude": -96.851778
            },
            {
                "id": 3550,
                "name": "George Bush Intercontinental",
                "city": "Houston",
                "faa": "IAH",
                "latitude": 29.984433,
                "longitude": -95.341442
            },
            {
                "id": 3559,
                "name": "El Paso Intl",
                "city": "El Paso",
                "faa": "ELP",
                "latitude": 31.80725,
                "longitude": -106.377583
            },
            {
                "id": 3566,
                "name": "William P Hobby",
                "city": "Houston",
                "faa": "HOU",
                "latitude": 29.645419,
                "longitude": -95.278889
            },
            {
                "id": 3570,
                "name": "Pittsburgh Intl",
                "city": "Pittsburgh",
                "faa": "PIT",
                "latitude": 40.491467,
                "longitude": -80.232872
            },
            {
                "id": 3576,
                "name": "Miami Intl",
                "city": "Miami",
                "faa": "MIA",
                "latitude": 25.79325,
                "longitude": -80.290556
            },
            {
                "id": 3582,
                "name": "Long Beach",
                "city": "Long Beach",
                "faa": "LGB",
                "latitude": 33.817722,
                "longitude": -118.151611
            },
            {
                "id": 3585,
                "name": "Indianapolis Intl",
                "city": "Indianapolis",
                "faa": "IND",
                "latitude": 39.717331,
                "longitude": -86.294383
            },
            {
                "id": 3589,
                "name": "Westchester Co",
                "city": "White Plains",
                "faa": "HPN",
                "latitude": 41.066959,
                "longitude": -73.707575
            },
            {
                "id": 3697,
                "name": "La Guardia",
                "city": "New York",
                "faa": "LGA",
                "latitude": 40.777245,
                "longitude": -73.872608
            },
            {
                "id": 3747,
                "name": "Chicago Midway Intl",
                "city": "Chicago",
                "faa": "MDW",
                "latitude": 41.785972,
                "longitude": -87.752417
            },
            {
                "id": 3797,
                "name": "John F Kennedy Intl",
                "city": "New York",
                "faa": "JFK",
                "latitude": 40.639751,
                "longitude": -73.778925
            },
            {
                "id": 3830,
                "name": "Chicago Ohare Intl",
                "city": "Chicago",
                "faa": "ORD",
                "latitude": 41.978603,
                "longitude": -87.904842
            }
        ]

        d3.selectAll('.close').on('click', function () {
            d3.selectAll('.popup').remove()
        })
        data.forEach(function (d) {
            d.latitude = +d.latitude;
            d.longitude = +d.longitude;
        })
        d3.selectAll('.location').remove()

        let locations = places.selectAll(".location")
            .data(data);

        locations.enter()
            .append("circle")
            .attr('id', d => 'n' + d.id)
            .attr("class", 'location')
            .attr('cx', d => projection([d.longitude, d.latitude])[0])
            .attr('cy', d => projection([d.longitude, d.latitude])[1])
            .each(d=>[d.x,d.y] = projection([d.longitude, d.latitude]))
            .attr("r", 5)
            .attr('fill', 'green')
            .style('stroke', '#fff')
            .style('stroke-width', .5)
            .style("opacity", .75)
            .on('click', function (event, d) {
                simulation.stop()

                var isSelectedCode = d.detention_facility_code
                var isSelectedName = d.name
                var whichclass = d3.select(this).attr("class").split(' ');
                let activeIndex = whichclass.indexOf('active')

                var sel = d3.select(this);
                sel.raise();

                let latlng = [d.longitude, d.latitude]
                $('#clickedFacility').text(d.name)
                $('#slider').removeClass('hide')
                showRadius(latlng, far)

            })
            .on("mouseover", function (event, d) {
                var sel = d3.select(this);
                sel.raise();

                let tooltip_str = d.name
                tooltip.html(tooltip_str)
                    .style("visibility", "visible");
            })
            .on("mousemove", function (event, d) {
                tooltip.style("top", event.pageY - (tooltip.node().clientHeight + 5) + "px")
                    .style("left", event.pageX - (tooltip.node().clientWidth / 2.0) + "px");
            })
            .on("mouseout", function (event, d) {
                var sel = d3.select(this);
                sel.lower();
                tooltip.style("visibility", "hidden");
            })

        locations
            .transition()
            .duration(100)
            .attr("class", d => "location " + d.name.replace(/[\s]/g, '') + ' ' + d.type_detailed.replace(/\s+|[,\/]/g, "") + ' closed' + d.is_closed)
            .attr("r", 5)
            .attr('fill', 'green')

        locations.exit()
            .remove();

        const tooltip = d3.select("body").append("div")
            .attr("class", "tooltip");

        var info = svg.append("div")
            .attr("class", "info");

        const quadtree = d3.quadtree()
            .x(d => +d.longitude)
            .y(d => +d.latitude)
            .addAll(data);

        let miles = 30

        let far = (1 / 60) * miles; // in degrees

        function showRadius(evt, far) {
        
            // Reset //
             svg.selectAll('circle')
                 .attr('cx', d => d.x = projection([d.longitude, d.latitude])[0])
                 .attr('cy', d => d.y = projection([d.longitude, d.latitude])[1])       
                 .attr('fill', 'green')
            /////
        

            d3.select('ellipse.radius').remove();

            let radiusCircle = map.append("ellipse").classed("radius", true).attr('id', 'locate')

            let xy = projection.invert(evt)
            console.log('xy', xy)

            let xyObject = { "longitude": evt[0], "latitude": evt[1] }
            radiusLng = evt[0] + far
            radiusLat = evt[1] + far
            radiusLngLat = [+radiusLng, +radiusLat]
            radiusPoint = projection(radiusLngLat)
            console.log('radiusPoint', radiusPoint)

            radiusX = Math.abs(evt[1] + far)
            radiusY = Math.abs(evt[0] + far)

            radiusToPoint = projection([radiusY, radiusX][0])

            d3.select('ellipse.radius').classed('hide', false)
            d3.select('ellipse.radius').classed('show', true)

            let radiusprojx = projection(evt)[0]
            let radiusprojxN = projection(evt)[0] - eventX
            let radiusprojy = projection(evt)[1]
            let radiusprojyN = projection(evt)[1] - eventY

            radiusCircle
                .attr('cx', d => (projection(evt)[0]))
                .attr('cy', d => (projection(evt)[1]))
                .attr('rx', 20)
                .attr('ry', 20)

            let hits = [];
            quadtree.visit(nearest(xyObject, far, hits))

            for (i = 0; i < hits.length; i++) {
                let line = turf.lineString([[evt[1], evt[0]], [hits[i].latitude, hits[i].longitude]]);
                let length = turf.length(line, { units: 'miles' });
                hits[i].distance = +length.toFixed(2) + ' miles';
            }
            hits.sort(function (a, b) { return d3.ascending(a.distance, b.distance) })

            let locationsInRadius = hits.map(a => a.id);
            //console.log('locationsInRadius', locationsInRadius)

            d3.selectAll('.location').attr('fill', 'green')
            locationsInRadius.forEach(function (d, i) {
                d3.select('#n' + d).attr('fill', 'blue')
            })

            let total_count = hits.length

            $("#hitnumber").text(total_count + " airports within 30 miles")

            d3.selectAll('.list-item').remove()

            let listItem = d3.selectAll('#hits').selectAll('text')
                .data(hits)
                .attr('padding-left', '20px')
                .enter().append('div').attr('class', 'list-item')
                .html(d => d.name + "<br/>Lat: " + d.latitude + "<br/>Lng: " + d.longitude + "<br/>Distance: " + d.distance)

            if (hits.length == 1) {
            } else {
                const hitids = []

                for (i = 0; i < hits.length; i++) {
                    hitids.push('#n' + hits[i].id)
                }
                let idstoget = hitids.toString()

                let forceids = d3.selectAll(idstoget)

                simulation.force('x', d3.forceX().strength(0.1).x(radiusPoint[0]))
                simulation.force('y', d3.forceY().strength(0.1).y(radiusPoint[1]))

                // simulation.force('center', d3.forceCenter(radiusPoint[0], radiusPoint[1]))

                simulation.alpha(1).restart()

                simulation.nodes(forceids.data())
                    .on('tick', ticked)

                function ticked() {
                    update(forceids)
                }

                function update(forceids) {

                    forceids
                        .attr('cx', function (d) { return d.x })
                        .attr('cy', function (d) { return d.y })
                }
            }
        }

        function nearest(node, radius, hits) {
            if (!hits) hits = [];
            var r = radius,
                nx1 = node.longitude - r,
                nx2 = node.longitude + r,
                ny1 = node.latitude - r,
                ny2 = node.latitude + r;

            return function (quad, x1, y1, x2, y2) {
                if (quad.data && (quad.data !== node)) {
                    var x = node.longitude - quad.data.longitude,
                        y = node.latitude - quad.data.latitude,
                        l = Math.sqrt(x * x + y * y),
                        r = radius;
                    if (l < r) {
                        hits.push(quad.data)
                    } else {
                    }
                }
                return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
            }
        }
.tooltip {
            position: absolute;
            padding: 15px;
            font: 12px sans-serif;
            background: #fff;
            color: #000;
            border: 0px;
            pointer-events: none;
            opacity: 0.8;
            visibility: hidden;
            -moz-box-shadow: 0 0 15px #aaa;
            -webkit-box-shadow: 0 0 15px #aaa;
            box-shadow: 0 0 15px #aaa;
        }

        .close {
            float: right;
            margin-top: 1 px;
        }

        .multiple-choice {
            padding: 3px 0;
        }

        .radius {
            fill-opacity: 0.15;
            stroke: #333;
            stroke-dasharray: 4 2;
            z-index: 1000;
            fill: #bff4ff;
            display: none;
        }

        #panel {
            position: absolute;
            left: 1030px;
            top: 0px;
            width: 300px;
            padding-top: 50px;
        }

        .list-item {
            padding: 10px;
        }

        label {
            margin: 0;
            padding: 0;
            font-family: Arial, Helvetica, sans-serif;
        }

        #hitnumber {
            font-family: Arial, Helvetica, sans-serif;
            padding-left: 10px;
        }

        .hide {
            display: none;
        }
<script src="https://cdn.jsdelivr.net/npm/d3-quadtree@3"></script>
    <script src="https://d3js.org/d3.v6.min.js"></script>
    <script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="https://unpkg.com/topojson-client@3"></script>
    <script src="https://unpkg.com/geo-albers-usa-territories@0.1.0/dist/geo-albers-usa-territories.js"></script>
    <div id="content"></div>
    <div id="panel">
        <div id="list">
            <div id="hitnumber"></div>
            <pre><div id="hits"></div></pre>
        </div>
    </div>
    <div id="chart-title"></div>
.each(d=>[d.x,d.y] = projection([d.longitude, d.latitude]))
simulation.nodes(forceids.data())
let margin = { top: 0, right: 0, bottom: 10, left: 0 },
            width = 1000 - margin.left - margin.right,
            height = 800 - margin.top - margin.bottom;

        let projection = geoAlbersUsaTerritories.geoAlbersUsaTerritories()
            .scale(width)
            .translate([width / 2, height / 2.2]);

        const path = d3.geoPath()
            .projection(projection);

        var simulation = d3.forceSimulation()
            .force('charge', d3.forceManyBody().strength(-160))
            .stop()

        let eventX,
            eventY

        const formatDate2 = d3.timeFormat("%m-%Y")

        const svg = d3.select("#content")
            .append("svg")
            .attr('id', 'map')
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)

        const map = svg.append('g')
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .attr('class', 'map')

        const landmass = map.append('g').attr('class', 'land')

        const places = map.append('g').attr('id', 'places')

        svg.append('ellipse').classed("radius", true).attr('id', 'locate')

        d3.json("https://unpkg.com/us-atlas@3.0.0/states-10m.json").then(function (usa) {

            landmass.selectAll('path')
                .data(topojson.feature(usa, usa.objects.nation).features)
                .enter().append("path")
                .attr("d", path)
                .attr("class", "outline")
                .attr('fill', '#ccc')
                .attr("stroke", "#999")

            landmass.append("path")
                .datum(topojson.mesh(usa, usa.objects.states, function (a, b) { return a !== b; }))
                .attr("class", "mesh")
                .attr("d", path)
                .attr('fill', 'none')
                .attr('stroke', 'white')
        });

        const data = [
            {
                "id": 3448,
                "name": "General Edward Lawrence Logan Intl",
                "city": "Boston",
                "faa": "BOS",
                "latitude": 42.364347,
                "longitude": -71.005181
            },
            {
                "id": 3453,
                "name": "Metropolitan Oakland Intl",
                "city": "Oakland",
                "faa": "OAK",
                "latitude": 37.721278,
                "longitude": -122.220722
            },
            {
                "id": 3454,
                "name": "Eppley Afld",
                "city": "Omaha",
                "faa": "OMA",
                "latitude": 41.303167,
                "longitude": -95.894069
            },
            {
                "id": 3457,
                "name": "Wichita Mid Continent",
                "city": "Wichita",
                "faa": "ICT",
                "latitude": 37.649944,
                "longitude": -97.433056
            },
            {
                "id": 3458,
                "name": "Kansas City Intl",
                "city": "Kansas City",
                "faa": "MCI",
                "latitude": 39.297606,
                "longitude": -94.713905
            },
            {
                "id": 3459,
                "name": "Dane Co Rgnl Truax Fld",
                "city": "Madison",
                "faa": "MSN",
                "latitude": 43.139858,
                "longitude": -89.337514
            },
            {
                "id": 3462,
                "name": "Phoenix Sky Harbor Intl",
                "city": "Phoenix",
                "faa": "PHX",
                "latitude": 33.434278,
                "longitude": -112.011583
            },
            {
                "id": 3467,
                "name": "Spokane Intl",
                "city": "Spokane",
                "faa": "GEG",
                "latitude": 47.619861,
                "longitude": -117.533833
            },
            {
                "id": 3469,
                "name": "San Francisco Intl",
                "city": "San Francisco",
                "faa": "SFO",
                "latitude": 37.618972,
                "longitude": -122.374889
            },
            {
                "id": 3472,
                "name": "Gainesville Rgnl",
                "city": "Gainesville",
                "faa": "GNV",
                "latitude": 29.690056,
                "longitude": -82.271778
            },
            {
                "id": 3473,
                "name": "Memphis Intl",
                "city": "Memphis",
                "faa": "MEM",
                "latitude": 35.042417,
                "longitude": -89.976667
            },
            {
                "id": 3484,
                "name": "Los Angeles Intl",
                "city": "Los Angeles",
                "faa": "LAX",
                "latitude": 33.942536,
                "longitude": -118.408075
            },
            {
                "id": 3486,
                "name": "Cleveland Hopkins Intl",
                "city": "Cleveland",
                "faa": "CLE",
                "latitude": 41.411689,
                "longitude": -81.849794
            },            
            {
                "id": 3494,
                "name": "Newark Liberty Intl",
                "city": "Newark",
                "faa": "EWR",
                "latitude": 40.6925,
                "longitude": -74.168667
            },
            {
                "id": 3502,
                "name": "Dallas Love Fld",
                "city": "Dallas",
                "faa": "DAL",
                "latitude": 32.847111,
                "longitude": -96.851778
            },
            {
                "id": 3550,
                "name": "George Bush Intercontinental",
                "city": "Houston",
                "faa": "IAH",
                "latitude": 29.984433,
                "longitude": -95.341442
            },
            {
                "id": 3559,
                "name": "El Paso Intl",
                "city": "El Paso",
                "faa": "ELP",
                "latitude": 31.80725,
                "longitude": -106.377583
            },
            {
                "id": 3566,
                "name": "William P Hobby",
                "city": "Houston",
                "faa": "HOU",
                "latitude": 29.645419,
                "longitude": -95.278889
            },
            {
                "id": 3570,
                "name": "Pittsburgh Intl",
                "city": "Pittsburgh",
                "faa": "PIT",
                "latitude": 40.491467,
                "longitude": -80.232872
            },
            {
                "id": 3576,
                "name": "Miami Intl",
                "city": "Miami",
                "faa": "MIA",
                "latitude": 25.79325,
                "longitude": -80.290556
            },
            {
                "id": 3582,
                "name": "Long Beach",
                "city": "Long Beach",
                "faa": "LGB",
                "latitude": 33.817722,
                "longitude": -118.151611
            },
            {
                "id": 3585,
                "name": "Indianapolis Intl",
                "city": "Indianapolis",
                "faa": "IND",
                "latitude": 39.717331,
                "longitude": -86.294383
            },
            {
                "id": 3589,
                "name": "Westchester Co",
                "city": "White Plains",
                "faa": "HPN",
                "latitude": 41.066959,
                "longitude": -73.707575
            },
            {
                "id": 3697,
                "name": "La Guardia",
                "city": "New York",
                "faa": "LGA",
                "latitude": 40.777245,
                "longitude": -73.872608
            },
            {
                "id": 3747,
                "name": "Chicago Midway Intl",
                "city": "Chicago",
                "faa": "MDW",
                "latitude": 41.785972,
                "longitude": -87.752417
            },
            {
                "id": 3797,
                "name": "John F Kennedy Intl",
                "city": "New York",
                "faa": "JFK",
                "latitude": 40.639751,
                "longitude": -73.778925
            },
            {
                "id": 3830,
                "name": "Chicago Ohare Intl",
                "city": "Chicago",
                "faa": "ORD",
                "latitude": 41.978603,
                "longitude": -87.904842
            }
        ]

        d3.selectAll('.close').on('click', function () {
            d3.selectAll('.popup').remove()
        })
        data.forEach(function (d) {
            d.latitude = +d.latitude;
            d.longitude = +d.longitude;
        })
        d3.selectAll('.location').remove()

        let locations = places.selectAll(".location")
            .data(data);

        locations.enter()
            .append("circle")
            .attr('id', d => 'n' + d.id)
            .attr("class", 'location')
            .attr('cx', d => projection([d.longitude, d.latitude])[0])
            .attr('cy', d => projection([d.longitude, d.latitude])[1])
            .each(d=>[d.x,d.y] = projection([d.longitude, d.latitude]))
            .attr("r", 5)
            .attr('fill', 'green')
            .style('stroke', '#fff')
            .style('stroke-width', .5)
            .style("opacity", .75)
            .on('click', function (event, d) {
                simulation.stop()

                var isSelectedCode = d.detention_facility_code
                var isSelectedName = d.name
                var whichclass = d3.select(this).attr("class").split(' ');
                let activeIndex = whichclass.indexOf('active')

                var sel = d3.select(this);
                sel.raise();

                let latlng = [d.longitude, d.latitude]
                $('#clickedFacility').text(d.name)
                $('#slider').removeClass('hide')
                showRadius(latlng, far)

            })
            .on("mouseover", function (event, d) {
                var sel = d3.select(this);
                sel.raise();

                let tooltip_str = d.name
                tooltip.html(tooltip_str)
                    .style("visibility", "visible");
            })
            .on("mousemove", function (event, d) {
                tooltip.style("top", event.pageY - (tooltip.node().clientHeight + 5) + "px")
                    .style("left", event.pageX - (tooltip.node().clientWidth / 2.0) + "px");
            })
            .on("mouseout", function (event, d) {
                var sel = d3.select(this);
                sel.lower();
                tooltip.style("visibility", "hidden");
            })

        locations
            .transition()
            .duration(100)
            .attr("class", d => "location " + d.name.replace(/[\s]/g, '') + ' ' + d.type_detailed.replace(/\s+|[,\/]/g, "") + ' closed' + d.is_closed)
            .attr("r", 5)
            .attr('fill', 'green')

        locations.exit()
            .remove();

        const tooltip = d3.select("body").append("div")
            .attr("class", "tooltip");

        var info = svg.append("div")
            .attr("class", "info");

        const quadtree = d3.quadtree()
            .x(d => +d.longitude)
            .y(d => +d.latitude)
            .addAll(data);

        let miles = 30

        let far = (1 / 60) * miles; // in degrees

        function showRadius(evt, far) {
        
            // Reset //
             svg.selectAll('circle')
                 .attr('cx', d => d.x = projection([d.longitude, d.latitude])[0])
                 .attr('cy', d => d.y = projection([d.longitude, d.latitude])[1])       
                 .attr('fill', 'green')
            /////
        

            d3.select('ellipse.radius').remove();

            let radiusCircle = map.append("ellipse").classed("radius", true).attr('id', 'locate')

            let xy = projection.invert(evt)
            console.log('xy', xy)

            let xyObject = { "longitude": evt[0], "latitude": evt[1] }
            radiusLng = evt[0] + far
            radiusLat = evt[1] + far
            radiusLngLat = [+radiusLng, +radiusLat]
            radiusPoint = projection(radiusLngLat)
            console.log('radiusPoint', radiusPoint)

            radiusX = Math.abs(evt[1] + far)
            radiusY = Math.abs(evt[0] + far)

            radiusToPoint = projection([radiusY, radiusX][0])

            d3.select('ellipse.radius').classed('hide', false)
            d3.select('ellipse.radius').classed('show', true)

            let radiusprojx = projection(evt)[0]
            let radiusprojxN = projection(evt)[0] - eventX
            let radiusprojy = projection(evt)[1]
            let radiusprojyN = projection(evt)[1] - eventY

            radiusCircle
                .attr('cx', d => (projection(evt)[0]))
                .attr('cy', d => (projection(evt)[1]))
                .attr('rx', 20)
                .attr('ry', 20)

            let hits = [];
            quadtree.visit(nearest(xyObject, far, hits))

            for (i = 0; i < hits.length; i++) {
                let line = turf.lineString([[evt[1], evt[0]], [hits[i].latitude, hits[i].longitude]]);
                let length = turf.length(line, { units: 'miles' });
                hits[i].distance = +length.toFixed(2) + ' miles';
            }
            hits.sort(function (a, b) { return d3.ascending(a.distance, b.distance) })

            let locationsInRadius = hits.map(a => a.id);
            //console.log('locationsInRadius', locationsInRadius)

            d3.selectAll('.location').attr('fill', 'green')
            locationsInRadius.forEach(function (d, i) {
                d3.select('#n' + d).attr('fill', 'blue')
            })

            let total_count = hits.length

            $("#hitnumber").text(total_count + " airports within 30 miles")

            d3.selectAll('.list-item').remove()

            let listItem = d3.selectAll('#hits').selectAll('text')
                .data(hits)
                .attr('padding-left', '20px')
                .enter().append('div').attr('class', 'list-item')
                .html(d => d.name + "<br/>Lat: " + d.latitude + "<br/>Lng: " + d.longitude + "<br/>Distance: " + d.distance)

            if (hits.length == 1) {
            } else {
                const hitids = []

                for (i = 0; i < hits.length; i++) {
                    hitids.push('#n' + hits[i].id)
                }
                let idstoget = hitids.toString()

                let forceids = d3.selectAll(idstoget)

                simulation.force('x', d3.forceX().strength(0.1).x(radiusPoint[0]))
                simulation.force('y', d3.forceY().strength(0.1).y(radiusPoint[1]))

                // simulation.force('center', d3.forceCenter(radiusPoint[0], radiusPoint[1]))

                simulation.alpha(1).restart()

                simulation.nodes(forceids.data())
                    .on('tick', ticked)

                function ticked() {
                    update(forceids)
                }

                function update(forceids) {

                    forceids
                        .attr('cx', function (d) { return d.x })
                        .attr('cy', function (d) { return d.y })
                }
            }
        }

        function nearest(node, radius, hits) {
            if (!hits) hits = [];
            var r = radius,
                nx1 = node.longitude - r,
                nx2 = node.longitude + r,
                ny1 = node.latitude - r,
                ny2 = node.latitude + r;

            return function (quad, x1, y1, x2, y2) {
                if (quad.data && (quad.data !== node)) {
                    var x = node.longitude - quad.data.longitude,
                        y = node.latitude - quad.data.latitude,
                        l = Math.sqrt(x * x + y * y),
                        r = radius;
                    if (l < r) {
                        hits.push(quad.data)
                    } else {
                    }
                }
                return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
            }
        }
.tooltip {
            position: absolute;
            padding: 15px;
            font: 12px sans-serif;
            background: #fff;
            color: #000;
            border: 0px;
            pointer-events: none;
            opacity: 0.8;
            visibility: hidden;
            -moz-box-shadow: 0 0 15px #aaa;
            -webkit-box-shadow: 0 0 15px #aaa;
            box-shadow: 0 0 15px #aaa;
        }

        .close {
            float: right;
            margin-top: 1 px;
        }

        .multiple-choice {
            padding: 3px 0;
        }

        .radius {
            fill-opacity: 0.15;
            stroke: #333;
            stroke-dasharray: 4 2;
            z-index: 1000;
            fill: #bff4ff;
            display: none;
        }

        #panel {
            position: absolute;
            left: 1030px;
            top: 0px;
            width: 300px;
            padding-top: 50px;
        }

        .list-item {
            padding: 10px;
        }

        label {
            margin: 0;
            padding: 0;
            font-family: Arial, Helvetica, sans-serif;
        }

        #hitnumber {
            font-family: Arial, Helvetica, sans-serif;
            padding-left: 10px;
        }

        .hide {
            display: none;
        }
<script src="https://cdn.jsdelivr.net/npm/d3-quadtree@3"></script>
    <script src="https://d3js.org/d3.v6.min.js"></script>
    <script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="https://unpkg.com/topojson-client@3"></script>
    <script src="https://unpkg.com/geo-albers-usa-territories@0.1.0/dist/geo-albers-usa-territories.js"></script>
    <div id="content"></div>
    <div id="panel">
        <div id="list">
            <div id="hitnumber"></div>
            <pre><div id="hits"></div></pre>
        </div>
    </div>
    <div id="chart-title"></div>

d3 svg shadow difference

copy iconCopydownload iconDownload
var filter = defs.append("filter").attr("id", id)
    .attr("height", "300%")
    .attr("width", "300%")
    .attr("x", "-100%")
    .attr("y", "-100%");
var filter = defs.append("filter").attr("id", id)
    .attr("primitiveUnits", "objectBoundingBox");

  filter
    .append("feGaussianBlur")
    .attr("in", "SourceAlpha")
    .attr("stdDeviation", "0.1")
    .attr("result", "blur");
var filter = defs.append("filter").attr("id", id)
    .attr("height", "300%")
    .attr("width", "300%")
    .attr("x", "-100%")
    .attr("y", "-100%");
var filter = defs.append("filter").attr("id", id)
    .attr("primitiveUnits", "objectBoundingBox");

  filter
    .append("feGaussianBlur")
    .attr("in", "SourceAlpha")
    .attr("stdDeviation", "0.1")
    .attr("result", "blur");

Convert d3v6 Observable example using zoom.center

copy iconCopydownload iconDownload
zoom.center = function(_) {
    return arguments.length ? (center = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), zoom) : center;
  };
function defaultCenter(event) {
  return d3Selection.pointer(event, this);
}
zoom.center = function(_) {
    return arguments.length ? (center = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), zoom) : center;
  };
function defaultCenter(event) {
  return d3Selection.pointer(event, this);
}

Why this Quadtree Query often returns nothing?

copy iconCopydownload iconDownload
rW = constrain(randomGaussian(),-1,1)*width/6;
rH = constrain(randomGaussian(),-1,1)*height/6;
rW = -100;
rX = 500
x = 256;
w = 256;
         !(400 >= 512 || 600 <= 512)
/*-->*/  !(false || false)
/*-->*/  true //(yes, they intersect)
         !(rX-rW >= x+w || rX+rW <= x-w)
/*-->*/  !(500-(-100) >= 256+256 || 500+(-100) <= 256-256)
/*-->*/  !(600 >= 512 || 400 <= 0)
/*-->*/  !(true || false)
/*-->*/  false //(no, they do not intersect)
rW = abs(constrain(randomGaussian(),-1,1))*width/6;
rH = abs(constrain(randomGaussian(),-1,1))*height/6;
rW = constrain(randomGaussian(),-1,1)*width/6;
rH = constrain(randomGaussian(),-1,1)*height/6;
rW = -100;
rX = 500
x = 256;
w = 256;
         !(400 >= 512 || 600 <= 512)
/*-->*/  !(false || false)
/*-->*/  true //(yes, they intersect)
         !(rX-rW >= x+w || rX+rW <= x-w)
/*-->*/  !(500-(-100) >= 256+256 || 500+(-100) <= 256-256)
/*-->*/  !(600 >= 512 || 400 <= 0)
/*-->*/  !(true || false)
/*-->*/  false //(no, they do not intersect)
rW = abs(constrain(randomGaussian(),-1,1))*width/6;
rH = abs(constrain(randomGaussian(),-1,1))*height/6;
rW = constrain(randomGaussian(),-1,1)*width/6;
rH = constrain(randomGaussian(),-1,1)*height/6;
rW = -100;
rX = 500
x = 256;
w = 256;
         !(400 >= 512 || 600 <= 512)
/*-->*/  !(false || false)
/*-->*/  true //(yes, they intersect)
         !(rX-rW >= x+w || rX+rW <= x-w)
/*-->*/  !(500-(-100) >= 256+256 || 500+(-100) <= 256-256)
/*-->*/  !(600 >= 512 || 400 <= 0)
/*-->*/  !(true || false)
/*-->*/  false //(no, they do not intersect)
rW = abs(constrain(randomGaussian(),-1,1))*width/6;
rH = abs(constrain(randomGaussian(),-1,1))*height/6;
rW = constrain(randomGaussian(),-1,1)*width/6;
rH = constrain(randomGaussian(),-1,1)*height/6;
rW = -100;
rX = 500
x = 256;
w = 256;
         !(400 >= 512 || 600 <= 512)
/*-->*/  !(false || false)
/*-->*/  true //(yes, they intersect)
         !(rX-rW >= x+w || rX+rW <= x-w)
/*-->*/  !(500-(-100) >= 256+256 || 500+(-100) <= 256-256)
/*-->*/  !(600 >= 512 || 400 <= 0)
/*-->*/  !(true || false)
/*-->*/  false //(no, they do not intersect)
rW = abs(constrain(randomGaussian(),-1,1))*width/6;
rH = abs(constrain(randomGaussian(),-1,1))*height/6;
rW = constrain(randomGaussian(),-1,1)*width/6;
rH = constrain(randomGaussian(),-1,1)*height/6;
rW = -100;
rX = 500
x = 256;
w = 256;
         !(400 >= 512 || 600 <= 512)
/*-->*/  !(false || false)
/*-->*/  true //(yes, they intersect)
         !(rX-rW >= x+w || rX+rW <= x-w)
/*-->*/  !(500-(-100) >= 256+256 || 500+(-100) <= 256-256)
/*-->*/  !(600 >= 512 || 400 <= 0)
/*-->*/  !(true || false)
/*-->*/  false //(no, they do not intersect)
rW = abs(constrain(randomGaussian(),-1,1))*width/6;
rH = abs(constrain(randomGaussian(),-1,1))*height/6;

undefined reference to `boost::filesystem::path_traits::dispatch when linking library?

copy iconCopydownload iconDownload
boost::filesystem::path_traits::dispatch(boost::filesystem::directory_entry const&, std::string&, std::codecvt<wchar_t, char, __mbstate_t> const&)
boost::filesystem::path_traits::dispatch(boost::filesystem::directory_entry const&, std::__cxx11::basic_string<char, std::char_traits, std::allocator >&, std::codecvt<wchar_t, char, __mbstate_t> const&)
boost::filesystem::path_traits::dispatch(boost::filesystem::directory_entry const&, std::string&, std::codecvt<wchar_t, char, __mbstate_t> const&)
boost::filesystem::path_traits::dispatch(boost::filesystem::directory_entry const&, std::__cxx11::basic_string<char, std::char_traits, std::allocator >&, std::codecvt<wchar_t, char, __mbstate_t> const&)

I implemented Quad as BST, but I try to split it this way, but it's not working well

copy iconCopydownload iconDownload
if (wsplit == 0) {
    w1 = w;   // was missing
    w2 = w;   // was missing
    h1 = h / 2;
    h2 = h - h1;
    tx1 = tx; // was missing
    tx2 = tx; // was missing
    ty1 = ty; // was missing
    ty2 = ty + h1;
    wsplit = 1;
} else {
    // same issues here
    ...
}

Doughnut pie hybrid d3 version 4

copy iconCopydownload iconDownload
function setBubbleChart(width, index, data) {

  var diameter = width / 2; //take half/width

  var bubs = doughnutbubble.select(".place" + index).append("g")
    .attr("class", "bubs");

  bubs.attr("transform", "translate(" + -diameter / 2 + "," + -diameter / 2 + ")");

  var data = bubbledata(data);
  var bubble = d3.pack(data)
    .size([diameter, diameter])
    .padding(3);

  var nodes = d3.hierarchy(data).sum(d => d.value);

  var bubbles = bubs.selectAll('circle')
    .data(bubble(nodes).descendants());
  bubbles.enter()
    .filter(d => !d.children)
    .insert("circle")
    .attr('transform', function(d) {
      return 'translate(' + d.x + ',' + d.y + ')';
    })
    .attr('r', d => d.r)
    .style("fill", function(d) {
      return colores_google(d.data.groupid);
    });

  bubbles = bubbles.transition()
    .transition()
    .duration(250)
    .attr('transform', function(d) {
      return 'translate(' + d.x + ',' + d.y + ')';
    })
    .attr('r', d => d.r)
    .ease(d3.easeSin);
}

Community Discussions

Trending Discussions on QuadTree
  • How to free all memory blocks of a picture using quadree structure with different cases?
  • Rendering imageData to new canvas
  • How to display composed quadtrees using C language?
  • How can I use d3 force to space out overlapping points on a map
  • How to index nearby 3D points on the fly?
  • d3 svg shadow difference
  • Why a quadtree sometimes need a max number to hold in a node?
  • 2D overlapping rectangles occlusion
  • Convert d3v6 Observable example using zoom.center
  • Why this Quadtree Query often returns nothing?
Trending Discussions on QuadTree

QUESTION

How to free all memory blocks of a picture using quadree structure with different cases?

Asked 2022-Jan-15 at 16:18

Few weeks ago, I was trying to implement a function to display a quadtree. My current problem is concerning the same work, so I pass you this link for all the context: How to display composed quadtrees using C language?
(I'm using a few features that come from this post)

the quadtree structure:

typedef struct block_image
{
    int allBlack; //boolean
    struct block_image * son[4];
}block_image;
typedef block_image *image;

Currently, I’m working on a function to free all memory blocks of a quadtree. For example, if a quadtree is white, there is nothing to do because the pointer to the structure is already NULL. If a quadtree is black, we free the pointer and set it to NULL. Else, if it is a composed picture, we take care of freeing the space of the different sons.

summary: returns all blocks of an image to the memory.

My current program:

void freeMemory(image myImage)
{
    if(myImage == NULL)
    {
        return;
    }
    else if(myImage->allBlack)
    {
        free(myImage);
        myImage = NULL;
    }
    else
    {
        freeMemory(myImage->son[0]);
        freeMemory(myImage->son[1]);
        freeMemory(myImage->son[2]);
        freeMemory(myImage->son[3]);
    }  
}

However, I am not sure how to check my function. For exemple, I decided to create a white quadree and a black quadtree. But when I used freeMemory fonction and normalDisplay to see the representation of the two quadrees before and after, there was no difference.

printf("\nfreeMemory\n\n");
image white = Build_white();
image black = Build_black();
printf("before\n");
normalDisplay(black);
printf("\n");
printf("after\n");
freeMemory(black);
normalDisplay(black);
printf("\n");
printf("before\n");
normalDisplay(white);
printf("\nafter\n");
freeMemory(white);
normalDisplay(white);   
printf("\n");

The result:

enter image description here

As you can see, there was no difference between display before and after memory.

And this is the simplest case, after that it should also work with composed images,e.g.

  • N +BBNB B +N+NNB+NBNNBN.

Someone advised me to use valgrind, telling me that for my program to work, there must be as many malloc() as free(). But I don't really know how to interpret the results (and if it is really useful).

the result (My variable names was not in english so, affichageNormal == normalDisplay, Rendmemoire == freeMemory and Construit_noir == Build_black)

enter image description here

P.S. I also have two function isWhite and isBlack to tell if a picture is black (no white elements) or white (no black element):

int isWhite(image myImage)
{
    if(myImage == NULL)
    {
        return 1;
    }
    else if(myImage->allBlack)
    {
        return 0;
    }
    else if(isWhite(myImage->son[0]) && isWhite(myImage->son[1]) && isWhite(myImage->son[2]) && isWhite(myImage->son[3]))
    {
        return 1;
    }
    return 0;
}


int isblack(image myImage)
{
    if(myImage == NULL)
    {
        return 0;
    }
    else if(myImage->allBlack)
    {
        return 1;
    }
    else if(isBlack(myImage->son[0]) && isBlack(myImage->son[1]) && isBlack(myImage->son[2]) && isBlack(myImage->son[3]))
    {
        return 1;
    }
    return 0;
}

It may be useful for the function.

Edit: In case of doubt I also add the code of normalDisplay :

void normalDisplay(image myImage)
{
    if(myImage == NULL)
    {
        printf("B");
    }
    else if(myImage->allBlack)
    {
        printf("N");
    }
    else
    {
        printf("+");
        normalDisplay(myImage->son[0]);
        normalDispay(myImage->son[1]);
        normalDisplay(myImage->son[2]);
        normalDisplay(myImage->son[3]);
    }
}

ANSWER

Answered 2022-Jan-15 at 16:18

A robust way to free the memory from the quadtree is to make sure you feedback that a pointer no longer is pointing to valid memory. Since your current freeMemory only takes an block_image pointer, the function cannot convey this information back to the caller.

Better would be to change its interface to provide this facitily with another level of indirection.

void freeMemory(image *myImage) {
    if (myImage != NULL && *myImage != NULL) {
        int sonSize = sizeof((*myImage)->son) / sizeof((*myImage)->son[0]);
        while (sonSize) freeMemory(&(*myImage)->son[--sonSize]);
        free(*myImage);
        *myImage = NULL;
    }
}

On a side note, your original freeMemory does have a memory leak, but hoping you can figure that out.

This way, *myImage = NULL will convey this change to the caller. On the calling side it would look something like this:

puts("\nfreeMemory\n");
image white = Build_white();
image black = Build_black();
puts("before");
normalDisplay(black);
puts("");
puts("after");
freeMemory(&black);
normalDisplay(black);
puts("");
puts("before");
normalDisplay(white);
puts("\nafter");
freeMemory(&white);
normalDisplay(white);
puts("");

With this your normalDisplay will better provide you with an "image" of the situation.

Source https://stackoverflow.com/questions/70722684

Community Discussions, Code Snippets contain sources that include Stack Exchange Network

Vulnerabilities

No vulnerabilities reported

Install QuadTree

You can download it from GitHub.
You can use QuadTree like any standard Java library. Please include the the jar files in your classpath. You can also use any IDE and you can run and debug the QuadTree component as you would do with any other Java program. Best practice is to use a build tool that supports dependency management such as Maven or Gradle. For Maven installation, please refer maven.apache.org. For Gradle installation, please refer gradle.org .

Support

For any new features, suggestions and bugs create an issue on GitHub. If you have any questions check and ask questions on community page Stack Overflow .

DOWNLOAD this Library from

Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases
Explore Kits

Save this library and start creating your kit

Explore Related Topics

Share this Page

share link
Consider Popular Map Libraries
Try Top Libraries by roma98
Compare Map Libraries with Highest Support
Compare Map Libraries with Highest Quality
Compare Map Libraries with Highest Security
Compare Map Libraries with Permissive License
Compare Map Libraries with Highest Reuse
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases
Explore Kits

Save this library and start creating your kit

  • © 2022 Open Weaver Inc.