picture.html
HTML document, ASCII text
1
{% extends "default.html" %}
2
{% block title %}Picture {{ resource.title }} | gigadata{% endblock %}
3
{% macro shape_label(x, y, text) %}
4
{% if text %}
5
<a class="shape-label" style="left: {{ x * 100 }}%; top: {{ y * 100 }}%" href="/object/{{ text }}">
6
{{ text }}
7
</a>
8
{% endif %}
9
{% endmacro %}
10
{% block content %}
11
<x-frame style="--width: 768px">
12
<h1>{{ resource.title }}</h1>
13
<p>{{ resource.description }}</p>
14
{% if resource.replaced_by %}
15
<h2>Obsolete</h2>
16
<p>
17
This picture has been replaced by <a href="/picture/{{ resource.replaced_by.id }}">{{ resource.replaced_by.title }}</a>.
18
</p>
19
{% if have_permission %}
20
<form method="POST" action="/picture/{{ resource.id }}/remove-replacement">
21
<button class="button-flat" type="submit">Remove replacement</button>
22
</form>
23
{% endif %}
24
{% endif %}
25
<p>
26
<a href="{{ resource.origin_url }}">Original source</a> |
27
<a href="/raw/picture/{{ resource.id }}">View</a> |
28
<a href="/picture/{{ resource.id }}/get-annotations">Download annotations</a> |
29
<a href="/raw/picture/{{ resource.id }}" download="GigadataPicture_{{ resource.id }}{{ file_extension }}">Download</a> {% if have_permission %}|
30
<a href="/picture/{{ resource.id }}/annotate">Annotate</a> |
31
<a href="/picture/{{ resource.id }}/put-annotations-form">Submit JSON annotations</a> |
32
<a href="/picture/{{ resource.id }}/edit-metadata">Edit title or description</a>{% endif %} {% if current_user %}|
33
<a href="/picture/{{ resource.id }}/copy">Copy</a>{% endif %}
34
</p>
35
{% if have_permission %}
36
<details>
37
<summary>Delete</summary>
38
<a href="/picture/{{ resource.id }}/delete">Delete</a>
39
</details>
40
{% endif %}
41
<div id="annotation-zone">
42
<img id="annotation-image" src="/raw/picture/{{ resource.id }}" alt="{{ resource.title }}">
43
{% for region in resource.regions %}
44
{% if region.json.type == "bbox" %}
45
<svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}">
46
<rect x="{{ region.json.shape.x * size[0] }}"
47
y="{{ region.json.shape.y * size[1] }}"
48
width="{{ region.json.shape.w * size[0] }}"
49
height="{{ region.json.shape.h * size[1] }}"
50
fill="none" class="shape-bbox shape"
51
></rect>
52
{% set centre_x = region.json.shape.x + region.json.shape.w / 2 %}
53
{% set centre_y = region.json.shape.y + region.json.shape.h / 2 %}
54
</svg>
55
{% elif region.json.type == "polygon" %}
56
<svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}">
57
<polygon points="{% for point in region.json.shape %}{{ point.x * size[0] }},{{ point.y * size[1] }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon>
58
{% set top = region.json.shape | sort(attribute='y') | last %}
59
{% set left = region.json.shape | sort(attribute='x') | first %}
60
{% set bottom = region.json.shape | sort(attribute='y') | first %}
61
{% set right = region.json.shape | sort(attribute='x') | last %}
62
{% set centre_x = (left.x + right.x) / 2 %}
63
{% set centre_y = (top.y + bottom.y) / 2 %}
64
</svg>
65
{% elif region.json.type == "polyline" %}
66
<svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}">
67
<polyline points="{% for point in region.json.shape %}{{ point.x * size[0] }},{{ point.y * size[1] }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline>
68
{# Median point #}
69
{% set centre_x = region.json.shape | map(attribute="x") | median %}
70
{% set centre_y = region.json.shape | map(attribute="y") | median %}
71
</svg>
72
{% elif region.json.type == "point" %}
73
<svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}">
74
<circle cx="{{ region.json.shape.x * size[0] }}" cy="{{ region.json.shape.y * size[1] }}" r="0" fill="none" class="shape-point shape"></circle>
75
</svg>
76
{% endif %}
77
{{ shape_label(centre_x, centre_y, region.object_id) }}
78
{% endfor %}
79
</div>
80
<x-buttonbox>
81
<label>
82
<input type="checkbox" id="show-shapes" checked>
83
Show shapes
84
</label>
85
<label>
86
<input type="checkbox" id="show-objects" checked>
87
Show objects
88
</label>
89
</x-buttonbox>
90
{% set licences = resource.licences | map(attribute="licence") | list %}
91
{% set contains = resource.regions | map(attribute="object_id") | set | select | sort | list %}
92
<x-vbox>
93
<div class="icon-explainer">
94
<span>Type</span>
95
<span>{{ resource.nature.id }}</span>
96
<span>File format</span>
97
<span>{{ resource.file_format }}</span>
98
<span>Size</span>
99
<span>{{ size[0] }}×{{ size[1] }}</span>
100
<span>Number of regions</span>
101
<span>{{ resource.regions | length }}</span>
102
<span>Number of labelled regions</span>
103
<span>{{ resource.regions | selectattr("object_id") | list | length }}</span>
104
<span>Date uploaded</span>
105
<span>{{ resource.timestamp }}</span>
106
</div>
107
Contains objects: {{ contains | join(", ") }}
108
<x-hbox style="justify-content: space-between">
109
<small class="picture-licensing-info">
110
Available under:
111
{% for licence in licences %}
112
<a href="{{ licence.info_url }}" target="_blank">
113
{{ licence.title }}
114
</a>
115
{% if not loop.last %}, {% endif %}
116
{% endfor %}
117
</small>
118
<x-vbox class="picture-licence-logos">
119
{% for licence in licences %}
120
{% if licence.logo_url %}
121
{% if licence.info_url %}
122
<a href="{{ licence.info_url }}" target="_blank" tabindex="-1">
123
{# An equivalent link already exists, only one is focusable #}
124
<img src="{{ licence.logo_url }}" alt="{{ licence.title }}" class="licence-logo">
125
</a>
126
{% else %}
127
<img src="{{ licence.logo_url }}" alt="{{ licence.title }}" class="licence-logo">
128
{% endif %}
129
{% endif %}
130
{% endfor %}
131
</x-vbox>
132
</x-hbox>
133
<h2>Copies</h2>
134
<ul class="thumbnail-list">
135
{% for copy in resource.copies %}
136
<li>
137
<a href="/picture/{{ copy.id }}">
138
<div class="annotation-zone">
139
<img src="/raw/picture/{{ copy.id }}" alt="{{ copy.title }}">
140
141
{% for region in copy.regions %}
142
{% if region.json.type == "bbox" %}
143
<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}">
144
<rect x="{{ region.json.shape.x * copy.width }}"
145
y="{{ region.json.shape.y * copy.height }}"
146
width="{{ region.json.shape.w * copy.width }}"
147
height="{{ region.json.shape.h * copy.height }}"
148
fill="none" class="shape-bbox shape"
149
></rect>
150
</svg>
151
{% elif region.json.type == "polygon" %}
152
<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}">
153
<polygon points="{% for point in region.json.shape %}{{ point.x * copy.width }},{{ point.y * copy.height }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon>
154
</svg>
155
{% elif region.json.type == "polyline" %}
156
<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}">
157
<polyline points="{% for point in region.json.shape %}{{ point.x * copy.width }},{{ point.y * copy.height }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline>
158
</svg>
159
{% elif region.json.type == "point" %}
160
<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}">
161
<circle cx="{{ region.json.shape.x * copy.width }}" cy="{{ region.json.shape.y * copy.height }}" r="0" fill="none" class="shape-point shape"></circle>
162
</svg>
163
{% endif %}
164
{% endfor %}
165
</div>
166
<div class="list-detail">
167
{{ copy.title }}
168
</div>
169
</a>
170
<div class="list-more">
171
<form method="POST" action="/picture/{{ copy.id }}/mark-replacement">
172
<button type="submit">Designate replacement</button>
173
</form>
174
</div>
175
</li>
176
{% endfor %}
177
</x-vbox>
178
</x-frame>
179
{% endblock %}