Skip to content

Commit

Permalink
Merge pull request #151 from edwardchalstrey1/extend-shapesData
Browse files Browse the repository at this point in the history
Speed up world map loading
  • Loading branch information
edwardchalstrey1 authored May 24, 2024
2 parents c9ef093 + a92da32 commit b093ccb
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 82 deletions.
18 changes: 18 additions & 0 deletions seshat/apps/core/migrations/0065_alter_videoshapefile_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.0.3 on 2024-05-22 14:14

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0064_gadmcountries_gadmprovinces_gadmshapefile_and_more'),
]

operations = [
migrations.AlterField(
model_name='videoshapefile',
name='id',
field=models.AutoField(primary_key=True, serialize=False),
),
]
1 change: 1 addition & 0 deletions seshat/apps/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@ def __str__(self) -> str:
# Shapefile models

class VideoShapefile(models.Model):
id = models.AutoField(primary_key=True)
geom = models.MultiPolygonField()
simplified_geom = models.MultiPolygonField(null=True)
name=models.CharField(max_length=100)
Expand Down
6 changes: 0 additions & 6 deletions seshat/apps/core/static/core/js/map_functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,6 @@ function stopPlay() {
function storeYear() {
var year = document.getElementById('enterYear').value;
history.pushState(null, '', '/core/world_map/?year=' + year);
if (!allPolitiesLoaded) {
// Refresh the page to load all polities
location.reload();
var loadingTextElement = document.getElementById('loadingText');
loadingTextElement.innerHTML = 'Loading polities for <b>' + year + '</b>...';
}
}

function switchBaseMap() {
Expand Down
4 changes: 2 additions & 2 deletions seshat/apps/core/templates/core/polity_map.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ <h5>Base Map:</h5>

var displayedShapes = [];
// Load inital polity shapes for the displayed year
var shapesData = [
var polityMapShapesData = [
// JavaScript object representing shape data
{% for shape in content.shapes %}
{
Expand Down Expand Up @@ -143,7 +143,7 @@ <h5>Base Map:</h5>
// Add shapes to the map
// Don't plot them if "Base map only" checkbox selected
if (!document.getElementById('baseMapOnly').checked) {
shapesData.forEach(function (shape) {
polityMapShapesData.forEach(function (shape) {

// If the shape spans the selected year
if ((parseInt(shape.start_year) <= selectedYearInt && parseInt(shape.end_year) >= selectedYearInt)) {
Expand Down
84 changes: 54 additions & 30 deletions seshat/apps/core/templates/core/world_map.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@
<h3>Polities</h3>
<!-- Add a loading indicator -->
<div id="loadingIndicator">
<p id="loadingText" style="font-size: 16px;">Loading polities for all years...</p>
<p style="font-size: 16px;">Note: You may adjust the year<br>now to quickly load a year of interest,<br>but this will slow loading all polities!</p>
<p id="loadingText" style="font-size: 16px;">Loading all polities for all years...</p>
<div class="spinner"></div>
</div>
</legend>
Expand Down Expand Up @@ -141,12 +140,12 @@ <h3>Polities</h3>
<button id="minusButton" type="button" onclick="adjustSliderDown()">-</button>
<button id="plusButton" type="button" onclick="adjustSliderUp()">+</button><br>
<input type="range" name="dateSlide" id="dateSlide" min="{{ earliest_year }}" max="{{ latest_year }}" value="{{ display_year }}" class="slider" onchange="plotPolities(); storeYear()" style="width: 300px;"><br>
<label for="sliderDate">Selected year:</label><span id="sliderDate"></span><br><br>
<label for="sliderDate">Selected year:&nbsp;</label><span id="sliderDate"></span><br><br>
<label for="playButton">Run animation:</label>
<button id="playButton" type="button" onclick="startPlay()" disabled>▶️</button>
<button id="stopButton" type="button" onclick="stopPlay()" disabled></button><br>
<button id="playButton" type="button" onclick="startPlay()">▶️</button>
<button id="stopButton" type="button" onclick="stopPlay()"></button><br>
<label for="playRate">Animation speed:</label>
<input type="range" name="playRate" id="playRate" min="1" max="5" value="2" class="slider" onchange="plotPolities()" disabled><br>
<input type="range" name="playRate" id="playRate" min="1" max="5" value="2" class="slider" onchange="plotPolities()"><br>
<label for="opacitySlide">Opacity:</label>
<input type="range" name="opacitySlide" id="opacitySlide" min="0.1" max="1" step="0.1" value="0.5" class="slider" onchange="plotPolities()" style="width: 150px;"><br><br>
<!-- TODO: Uncomment this when there are more capitals with coordinates in the database -->
Expand Down Expand Up @@ -213,6 +212,7 @@ <h3>Base Map</h3>

var displayedShapes = [];
var polityBorderWeight = 0;
var polityBorderWeightSelected = 2;

// Load inital polity shapes for the displayed year
var shapesData = [
Expand All @@ -222,7 +222,6 @@ <h3>Base Map</h3>
{% for key, value in shape.items %}
'{{ key }}': '{{ value|escapejs }}',
{% endfor %}
'weight': polityBorderWeight,
},
{% endfor %}
];
Expand All @@ -249,6 +248,17 @@ <h3>Base Map</h3>
shape[key] = JSON.parse(newValue.replace(/'/g, '"'));
}
}

// Set the border weights for shapes
if (shape.seshat_id && shape.seshat_id === '{{ world_map_initial_polity }}') {
shape.weight = polityBorderWeightSelected;
} else {
shape.weight = polityBorderWeight;
}

// Convert shape.id to int
shape.id = parseInt(shape.id);

});

// Load seshat_id_page_id dictionary
Expand All @@ -260,17 +270,37 @@ <h3>Base Map</h3>
var provinceShapeData;
var countryShapeData;

var allPolitiesLoaded = false; // Used within storeYear() function

// Load all polity shapes and modern province/country shapes in background
window.addEventListener('load', function () {
fetch('/core/world_map_all/')
fetch('/core/world_map_one_year/')
.then(response => response.json())
.then(data => {
shapesData = data.shapes.map(function (shape) {
shape.weight = polityBorderWeight;
return shape;
});
data.shapes // Add the shapes from the url year to shapesData
.filter(shape => !shapesData.some(existingShape => existingShape.id === shape.id))
.forEach(shape => {
shape.weight = polityBorderWeight;
shapesData.push(shape);
});

// Update seshat_id_page_id from the JSON response
seshat_id_page_id = data.seshat_id_page_id;

// Update allCapitalsInfo from the JSON response
allCapitalsInfo = data.all_capitals_info;

// Call plotPolities() after shapesData is updated
plotPolities();

})
.then(() => fetch('/core/world_map_all/'))
.then(response => response.json())
.then(data => {
data.shapes // Add the rest of the shapes to shapesData
.filter(shape => !shapesData.some(existingShape => existingShape.id === shape.id))
.forEach(shape => {
shape.weight = polityBorderWeight;
shapesData.push(shape);
});

// Update seshat_id_page_id from the JSON response
seshat_id_page_id = data.seshat_id_page_id;
Expand All @@ -281,18 +311,12 @@ <h3>Base Map</h3>
// Call plotPolities() after shapesData is updated
plotPolities();

allPolitiesLoaded = true;
// Update the date slide to use the earliest and latest years
document.getElementById('dateSlide').min = data.earliest_year;
document.getElementById('dateSlide').max = data.latest_year;

// Hide the loading indicator and enable the buttons after the fetch request is done
// Hide the loading indicator after the fetch request is done
document.getElementById('loadingIndicator').style.display = 'none';
document.getElementById('enterYear').disabled = false;
document.getElementById('minusButton').disabled = false;
document.getElementById('plusButton').disabled = false;
document.getElementById('dateSlide').disabled = false;
document.getElementById('playButton').disabled = false;
document.getElementById('stopButton').disabled = false;
document.getElementById('playRate').disabled = false;
document.getElementById('chooseVariable').disabled = false;

// Start the second fetch after the first one is complete
return fetch('/core/provinces_and_countries');
Expand Down Expand Up @@ -435,7 +459,7 @@ <h3>Base Map</h3>
};
};
} else if (variable in categorical_variables){
shapeWeight = 2;
shapeWeight = polityBorderWeightSelected;
// If the shape has a dictionary for the variable the key of the dict is the variable value and the value is a list of start and end years.
// Iterate through it and choose the colour based on the number of that variable that are active in the selected year
var numberOfThisVariable = 0; // Number of different values of this variable that are active in the selected year
Expand Down Expand Up @@ -476,7 +500,7 @@ <h3>Base Map</h3>
}

} else { // Absent-present variables
shapeWeight = 2;
shapeWeight = polityBorderWeightSelected;
shapeColour = variableColourMapping[shape[variable]];
if (shape[variable + '_dict']) {
// Iterate through key/values in the dictionary
Expand Down Expand Up @@ -669,18 +693,18 @@ <h3>Base Map</h3>

// Listen for the click event on the layer
layer.on('click', function (e) {
if (allPolitiesLoaded && variable == 'polity'){
if (variable == 'polity'){
if (shape.weight === 0) {
// Increase the weight of the clicked layer
newWeight = 2;
newWeight = polityBorderWeightSelected;
this.setStyle({
weight: newWeight
});
// Open the popup
layer.openPopup();
} else {
// Decrease the weight of the clicked layer
newWeight = 0;
newWeight = polityBorderWeight;
// Close the popup
layer.closePopup();
};
Expand Down Expand Up @@ -790,7 +814,7 @@ <h3>Base Map</h3>
// var marker = L.circleMarker([capital.latitude, capital.longitude], {
// color: 'black', // Set the border color
// fillColor: shape.colour, // Set the fill color based on the "colour" field
// weight: 2, // Set the border weight
// weight: polityBorderWeightSelected, // Set the border weight
// fillOpacity: 0.5, // Set the fill opacity
// radius: 5
// });
Expand Down
26 changes: 18 additions & 8 deletions seshat/apps/core/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def setUp(self):
end_year=1100
)
self.video_shapefile = VideoShapefile.objects.create(
id=1,
geom=self.square,
simplified_geom=self.square,
name="Test shape",
Expand All @@ -56,6 +57,7 @@ def setUp(self):
colour="#FFFFFF"
)
VideoShapefile.objects.create(
id=2,
geom=self.square,
simplified_geom=self.square,
name="Test shape 2",
Expand Down Expand Up @@ -204,7 +206,8 @@ def test_get_polity_shape_content(self):
'polity_end_year': 2020,
'colour': "#FFFFFF",
'area': 100.0,
'geom': self.geo_square
'geom': self.geo_square,
'id': 1
},
{
'seshat_id': 'Test seshat_id 2',
Expand All @@ -216,7 +219,8 @@ def test_get_polity_shape_content(self):
'polity_end_year': 1000,
'colour': "#FFFFFF",
'area': 100.0,
'geom': self.geo_square
'geom': self.geo_square,
'id': 2
}
],
'earliest_year': 0,
Expand Down Expand Up @@ -248,7 +252,8 @@ def test_get_polity_shape_content_single_year(self):
'polity_end_year': 2020,
'colour': "#FFFFFF",
'area': 100.0,
'geom': self.geo_square
'geom': self.geo_square,
'id': 1
}
],
'earliest_year': 0, # This is the earliest year in the database, not the earliest year of the polity
Expand Down Expand Up @@ -279,7 +284,8 @@ def test_get_polity_shape_content_single_seshat_id(self):
'polity_end_year': 2020,
'colour': "#FFFFFF",
'area': 100.0,
'geom': self.geo_square
'geom': self.geo_square,
'id': 1
}
],
'earliest_year': 2000, # This is the earliest year of the polity
Expand Down Expand Up @@ -333,7 +339,8 @@ def test_polity_map(self):
'polity_end_year': 2020,
'colour': "#FFFFFF",
'area': 100.0,
'geom': self.geo_square
'geom': self.geo_square,
'id': 1
}
],
'earliest_year': 2000,
Expand Down Expand Up @@ -367,7 +374,8 @@ def test_polity_map_no_peak_year_set(self):
'polity_end_year': 1000,
'colour': "#FFFFFF",
'area': 100.0,
'geom': self.geo_square
'geom': self.geo_square,
'id': 2
}
],
'earliest_year': 0,
Expand Down Expand Up @@ -426,7 +434,8 @@ def test_assign_variables_to_shapes(self):
'polity_end_year': 1000,
'colour': "#FFFFFF",
'area': 100.0,
'geom': self.geo_square
'geom': self.geo_square,
'id': 2
}
]
app_map = {
Expand Down Expand Up @@ -465,7 +474,8 @@ def test_assign_categorical_variables_to_shapes(self):
'polity_end_year': 1000,
'colour': "#FFFFFF",
'area': 100.0,
'geom': self.geo_square
'geom': self.geo_square,
'id': 2
}
]
result_shapes, result_variables = assign_categorical_variables_to_shapes(shapes, {})
Expand Down
1 change: 1 addition & 0 deletions seshat/apps/core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,5 +165,6 @@

# Map urls
urlpatterns += [path('core/world_map/', views.map_view_initial, name='world_map'),]
urlpatterns += [path('core/world_map_one_year/', views.map_view_one_year, name='world_map_one_year'),]
urlpatterns += [path('core/world_map_all/', views.map_view_all, name='world_map_all'),]
urlpatterns += [path('core/provinces_and_countries', views.provinces_and_countries_view, name='provinces_and_countries'),]
Loading

0 comments on commit b093ccb

Please sign in to comment.