Exploring the concept of calculating scaled distance in TopoJSON files

I have been exploring various methods to connect pixel space with real-world distances using a projection. I came across the following method which proved to be quite useful:

var actual_map_bounds = d3.geo.bounds(this_topojson);

    var radians = d3.geo.distance(actual_map_bounds[0], actual_map_bounds[1]);
    var earth_radius = 3959;  // miles
    var arc_length = earth_radius * radians;  // s = r * theta

    var projected_map_bounds = [
      this_projection(actual_map_bounds[0]),
      this_projection(actual_map_bounds[1])
    ];

    var projected_map_width = projected_map_bounds[1][0] - projected_map_bounds[0][0];
    var projected_map_height = projected_map_bounds[0][1] - projected_map_bounds[1][1];
    var projected_map_hypotenuse = Math.sqrt(
      (Math.pow(projected_map_width, 2)) + (Math.pow(projected_map_height, 2))
    );

    var pixels_per_mile = projected_map_hypotenuse / arc_length;
    var pixel_distance = pixels_per_mile * miles;

However, I believe my current application could benefit greatly from simplifying the calculation process. I am curious if there are any more straightforward or 'elegant' solutions that can be utilized by topojson developers?

Answer №1

It seems like the main concern here lies in creating a reusable function in JavaScript without relying on global variables. The question at hand can be summed up as:

How can I create a function that avoids recalculating most of its values each time it runs, and instead maintains data for future use?

The solution to this is utilizing closures:

function pixelLength(this_topojson, this_projection) {

    var actual_map_bounds = d3.geo.bounds(this_topojson);

    var radians = d3.geo.distance(actual_map_bounds[0], actual_map_bounds[1]);
    var earth_radius = 3959;  // miles
    var arc_length = earth_radius * radians; 

    var projected_map_bounds = [
      this_projection(actual_map_bounds[0]),
      this_projection(actual_map_bounds[1])
    ];

    var projected_map_width = projected_map_bounds[1][0] - projected_map_bounds[0][0];
    var projected_map_height = projected_map_bounds[0][1] - projected_map_bounds[1][1];
    var projected_map_hypotenuse = Math.sqrt(
      (Math.pow(projected_map_width, 2)) + (Math.pow(projected_map_height, 2))
    );

    var pixels_per_mile = projected_map_hypotenuse / arc_length;

    return function(miles){
      var pixel_distance = pixels_per_mile * miles;
      return pixel_distance;
    }
  }

With this closure, you can now obtain a function from `pixelLength` that can repeatedly calculate pixel distances based on the same topojson and projection:

var pixelCalc = pixelLength(topojson.feature(data, data.objects['parishes']), projection4);

pixelCalc(1); // pixels for 1 mile
pixelCalc(100); // pixels for 100 miles

See it in action:

...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Question from Student: Can a single function be created to manage all text fields, regardless of the number of fields present?

In my SPFX project using React, TypeScript, and Office UI Fabric, I've noticed that I'm creating separate functions for each text field in a form. Is there a way to create a single function that can handle multiple similar fields, but still maint ...

The functionality of sending a response to a client in Node.js Express seems to be malfunctioning

I am facing an issue with sending a response back to the client. Despite not receiving any errors, it seems like the response is not working as expected. Can anyone help me figure out why? Below is my code snippet: exports.login = function (req, res, next ...

Guide to creating fog animations in three.js

I'm attempting to adjust the fog density using tweening, but for some reason, it doesn't seem to be working. Here are my default settings: var camera, densityFog, colorFog2; colorFog2 = 0xfee2ed; densityFog ...

What tools do Sketchfab and Thangs utilize to display 3D models?

My website functions as a digital library for a particular niche of 3D models. However, I've noticed that the performance on mobile devices when using modelviewer to display glb files is quite poor. Frequently, the page crashes and reloads unexpectedl ...

To utilize a spread argument, it is essential for it to either be in tuple form or be supplied to a rest

I am currently learning TypeScript and working on converting my project to TypeScript. However, I encountered an error while trying to use spread arguments. I have researched this topic, but I am still unsure of the correct usage. Here is my current appro ...

Is there a way to automate the distribution of tasks to users in order to ensure that each user receives an equal number of assignments?

I'm in the process of developing an automated task manager that assigns tasks to users based on their role. Currently, I'm randomly selecting a user with the same role as the task from the list of users and assigning the task to them using math.r ...

By utilizing // within the source of a <script>, one can efficiently reference external files without specifying the

Curious if anyone has come across any evidence, proof, or firsthand accounts of utilizing the traditional http/https JavaScript <script> hack: <script src="//someserver.com/js/script.js"></script> Have you faced any problems with this m ...

Creating a web form with the ability to select multiple images using Javascript

Currently, I am in the process of developing an HTML form that enables users to select an image, a URL, and text that will be inserted as a <li> into a webpage. However, I am facing an issue where I want users to create multiple <li> per input. ...

Whenever I try to launch my React app using the `npm start` command in my command

After successfully creating a Simple React App and getting the happy hacking message on cmd, I encountered numerous errors when trying to run "npm start" on cmd. Despite multiple attempts at uninstalling and reinstalling node and npm, the issue persists. H ...

Tips for toggling Bootstrap 5 tabs using JavaScript instead of the button version

I am looking to switch tabs programmatically using bootstrap 5. The Bootstrap documentation recommends using buttons for tabs instead of links for a dynamic change. Here is the code I have: $("#mybut").click(function() { var sel = document.querySelector( ...

Console.log() will not display any JSON duplicates

My JSON data structure is pretty flat and can have duplicate attributes. I built a logic to remove the duplicates but when testing it out, something strange happened. The logic was always counting the attributes once, resulting in no duplicates. To test th ...

Guard your website against Backdoor/PHP.C99Shell, also known as Trojan.Script.224490

Recently, my website fell victim to a trojan script infiltration. Someone maliciously inserted a file named "x76x09.php" or "config.php" into the root directory of my webspace. This file, with a size of 44287 bytes and an MD5 checksum of 8dd76fc074b717fcc ...

Sorting arrays with NaN values within objects will not result in a reordering when using the Array

I encountered a situation where I need to reorder items in an array based on the property minLVL of each object within the array. However, I have discovered that this reordering only works if the previous and next items have the required minLVL field. If ...

Manipulating DropDownList Attributes in ASP.NET using JavaScript

I am facing an issue with populating a Dropdownlist control on my ASCX page. <asp:DropDownList ID="demoddl" runat="server" onchange="apply(this.options[this.selectedIndex].value,event)" onclick="borderColorChange(this.id, 'Click')" onblur="bo ...

Get the Zip file content using PushStreamContent JavaScript

I am looking for the correct method to download a PushStreamContent within a Post request. I have already set up the backend request like this: private static HttpClient Client { get; } = new HttpClient(); public HttpResponseMessage Get() { var filenames ...

Is it possible to create a basic calculator with Vue.js by incorporating v-model and possibly v-if?

I am looking to create a Vue.Js component that includes an input field displaying the potential hours saved by a user switching to our software. How can I implement the v-if directive in this scenario? For users spending 20 - 30 hours, they would save 10 ...

JavaScript Filtering Techniques

Looking for a simpler way to remove an item from a list of 10 items without using arrow functions. My current method is shown below, but I'm seeking a more efficient solution. function getFilteredItems(myItems) { var items = ['item1& ...

Execute a Gulp task automatically following the installation of an NPM package, no need for

I have created a small Angular package that is available on npmjs. I need to modify the "selector" name when installing my package, so I wrote a gulp task as shown below: gulp.task('tag-change', function () { // var files = fs.readFileSync(&a ...

Modifying button text dynamically during save operation with AngularJS

Is it possible to dynamically change the text on a submit button while data is being saved in a form? Here's an example of the button: <button ng-click="save()">Save data</button> I have updated my save function based on some suggestion ...

The send_keys() function in Selenium version 3.141.0 works perfectly on Windows, but unfortunately, it is not functioning correctly on Linux Debian 11

I've been experimenting with web automation using Selenium. Everything was running smoothly until I updated my packages - now the send_keys() method isn't functioning on Linux, but it's working fine on Windows with the same versions. I&apo ...