-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmap-state-interface.js
More file actions
134 lines (115 loc) · 3.76 KB
/
map-state-interface.js
File metadata and controls
134 lines (115 loc) · 3.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// MapState Interface Definition
// Defines the contract that all MapState implementations must follow
/**
* Interface for MapState implementations
* This serves as documentation and can be used for runtime type checking
*/
class MapStateInterface {
/**
* Initialize the map state tracker
* @returns {boolean} True if initialization succeeded
*/
initialize() {
throw new Error('MapState.initialize() must be implemented');
}
/**
* Convert lat/lng to canvas pixel coordinates
* @param {number} lat - Latitude
* @param {number} lng - Longitude
* @returns {Object|null} Canvas coordinates {x, y} or null if error
*/
mapLatLngToCanvas(lat, lng) {
throw new Error('MapState.mapLatLngToCanvas() must be implemented');
}
/**
* Update position information from URL
*/
updatePositionFromUrl() {
throw new Error('MapState.updatePositionFromUrl() must be implemented');
}
/**
* Add a listener for map state changes
* @param {Function} callback - Called when state changes with (changeType, mapState)
*/
addChangeListener(callback) {
throw new Error('MapState.addChangeListener() must be implemented');
}
/**
* Remove a change listener
* @param {Function} callback - Callback to remove
*/
removeChangeListener(callback) {
throw new Error('MapState.removeChangeListener() must be implemented');
}
/**
* Handle URL changes
*/
handleUrlChanged() {
throw new Error('MapState.handleUrlChanged() must be implemented');
}
/**
* Handle potential zoom interactions
*/
handlePotentialZoomInteraction() {
throw new Error('MapState.handlePotentialZoomInteraction() must be implemented');
}
/**
* Clean up observers and listeners
*/
cleanup() {
throw new Error('MapState.cleanup() must be implemented');
}
/**
* Check if map state is valid
* @returns {boolean} True if state is valid
*/
isValid() {
throw new Error('MapState.isValid() must be implemented');
}
// Required properties
get center() {
throw new Error('MapState.center property must be implemented');
}
get zoom() {
throw new Error('MapState.zoom property must be implemented');
}
get isPotentiallyZooming() {
throw new Error('MapState.isPotentiallyZooming property must be implemented');
}
get viewMode() {
throw new Error('MapState.mode property must be implemented')
}
}
/**
* Utility function to validate that an object implements the MapState interface
* @param {Object} mapState - Object to validate
* @returns {boolean} True if object implements the interface
*/
function validateMapStateInterface(mapState) {
const requiredMethods = [
'initialize', 'mapLatLngToCanvas', 'updatePositionFromUrl',
'addChangeListener', 'removeChangeListener', 'handleUrlChanged',
'handlePotentialZoomInteraction', 'cleanup', 'isValid'
];
const requiredProperties = ['center', 'zoom', 'isPotentiallyZooming'];
// Check methods
for (const method of requiredMethods) {
if (typeof mapState[method] !== 'function') {
console.error(`MapState missing required method: ${method}`);
return false;
}
}
// Check properties (they can be getters)
for (const prop of requiredProperties) {
if (!(prop in mapState)) {
console.error(`MapState missing required property: ${prop}`);
return false;
}
}
return true;
}
// Export for use in other files
if (typeof window !== 'undefined') {
window.MapStateInterface = MapStateInterface;
window.validateMapStateInterface = validateMapStateInterface;
}