File : core/osmSearch/OsmSearchDictionary.js

1
/*
2
Copyright - 2017 2023 - wwwouaiebe - Contact: https://www.ouaie.be/
3
4
This  program is free software;
5
you can redistribute it and/or modify it under the terms of the
6
GNU General Public License as published by the Free Software Foundation;
7
either version 3 of the License, or any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
*/
18
/*
19
Changes:
20
    - v4.0.0:
21
        - created from v3.6.0
22
Doc reviewed 202208
23
 */
24
25
import DictionaryItem from './DictionaryItem.js';
26
import { NOT_FOUND, ZERO, ONE } from '../../main/Constants.js';
27
28
/* ------------------------------------------------------------------------------------------------------------------------- */
29
/**
30
This class contains the OsmSearch dictionary and methods to perform changes in the dictionary
31
32
See DictionaryItem for dictionary items
33
34
See theOsmSearchDictionary for the one and only one instance of this class
35
*/
36
/* ------------------------------------------------------------------------------------------------------------------------- */
37
38
class OsmSearchDictionary {
39
40
    /**
41
    the root item of the dictionary
42
    @type {DictionaryItem}
43
    */
44
45
    #dictionary;
46
47
    /**
48
    A map with the all the DictionaryItem created, selectable by their objId
49
    @type {Map}
50
    */
51
52
    #itemsMap;
53
54
    /**
55
    the currentItem treated by the #parseLine method
56
    @type {DictionaryItem}
57
    */
58
59
    #currentItem;
60
61
    /**
62
    Array used to store a reference to the items property  of the DictionaryItem Objects
63
    and so build the tree.
64
    @type {Array.<Array.<DictionaryItem>>}
65
    */
66
67
    #itemsArray;
68
69
    /**
70
    Split a line from the csv file into cells and add a DictionaryItem or a filterTag to the dictionary
71
    @param {String} line A line of the csv file that will be parsed
72
    */
73
74
    #parseLine ( line ) {
75
76
        // split the linres into cells
77
        const cells = line.split ( ';' );
78
79
        // removing empty cells at the end of the line
80
        while ( '' === cells [ cells.length - ONE ] ) {
81
            cells.pop ( );
82
        }
83
84
        // The cell position in line. Used to build the tree
85
        let cellPos = ZERO;
86
87
        // An array with filterTags objects used to filter the osm elements. See DictionaryItem
88
        const filterTags = [];
89
        cells.forEach (
90
            cell => {
91
                if ( '' !== cell ) {
92
93
                    // The cell contains something
94
                    if ( NOT_FOUND === cell.indexOf ( '=' ) ) {
95
96
                        // The cell don't contains the = char. A new DictionaryItem is created
97
                        this.#currentItem = new DictionaryItem ( cell );
98
99
                        // The item is added to the itemsMap
100
                        this.#itemsMap.set ( this.#currentItem.objId, this.#currentItem );
101
102
                        this.#itemsArray [ cellPos ].push ( this.#currentItem );
103
                        this.#itemsArray [ cellPos + ONE ] = this.#currentItem.items;
104
                    }
105
                    else {
106
107
                        // Each cell is splited into a key and a value
108
                        let keyAndValue = cell.split ( '=' );
109
110
                        if ( 'element' === keyAndValue [ ZERO ] ) {
111
112
                            // Only one elementType is acceptable for this item
113
                            this.#currentItem.setElementType ( keyAndValue [ ONE ] );
114
                        }
115
                        else {
116
117
                            // A filterTag object is created...
118
                            let filterTag = {};
119
120
                            // ...and a property added to the object. The property name is the key found in the cell
121
                            // and the property value is the value found in the cell, except when the value is *
122
                            filterTag [ keyAndValue [ ZERO ] ] =
123
                                '*' === keyAndValue [ ONE ] ? null : keyAndValue [ ONE ];
124
125
                            // ...and the filterTag object pushed in the array
126
                            filterTags.push ( filterTag );
127
                        }
128
                    }
129
                }
130
                cellPos ++;
131
            }
132
        );
133
        if ( ZERO !== filterTags.length ) {
134
            this.#currentItem.filterTagsArray.push ( filterTags );
135
        }
136
    }
137
138
    /**
139
    Mark as expanded an item and all the childrens
140
    @param {DictionaryItem} item The item to mark as expanded
141
    */
142
143
    #expand ( item ) {
144
        item.items.forEach (
145
            subItem => { this.#expand ( subItem ); }
146
        );
147
        item.isExpanded = true;
148
    }
149
150
    /**
151
    Mark as not expanded an item and all the childrens
152
    @param {DictionaryItem} item The item to mark as not expanded
153
    */
154
155
    #collapse ( item ) {
156
        item.items.forEach (
157
            subItem => { this.#collapse ( subItem ); }
158
        );
159
        item.isExpanded = false;
160
    }
161
162
    /**
163
    The constructor
164
    */
165
166
    constructor ( ) {
167
        this.#dictionary = new DictionaryItem ( '', true );
168
        this.#itemsMap = new Map ( );
169
        this.#itemsMap.set ( this.#dictionary.objId, this.#dictionary );
170
        this.#itemsArray = [ this.#dictionary.items ];
171
        Object.freeze ( this );
172
    }
173
174
    /**
175
    The dictionary
176
    @type {DictionaryItem}
177
    */
178
179
    get dictionary ( ) { return this.#dictionary; }
180
181
    /**
182
    Parse the content of the TravelNotesSearchDictionaryXX.csv and build a tree of DictionaryItem
183
    with this content
184
    @param {String} dictionaryTextContent The content of the TravelNotesSearchDictionaryXX.csv file
185
    */
186
187
    parseDictionary ( dictionaryTextContent ) {
188
189
        // split the dictionary content into lines and analyse each line
190
        dictionaryTextContent.split ( /\r\n|\r|\n/ ).forEach (
191
            line => {
192
                if ( '' !== line ) {
193
                    this.#parseLine ( line );
194
                }
195
            }
196
        );
197
    }
198
199
    /**
200
    Mark as selected/not selected an item identified by it's objId and all the chidrens of this item
201
    @param {Number} itemObjId The objId of the item
202
    @param {Boolean} isSelected The value to set for isSelected
203
    */
204
205
    selectItem ( itemObjId, isSelected ) {
206
        this.#itemsMap.get ( itemObjId ).isSelected = isSelected;
207
    }
208
209
    /**
210
    Mark the complete dictionary as not selected
211
    */
212
213
    unselectAll ( ) {
214
        this.#dictionary.isSelected = false;
215
    }
216
217
    /**
218
    Mark as expanded an item identified by it's objId
219
    @param {Number} itemObjId The objId of the item
220
    */
221
222
    expandItem ( itemObjId ) {
223
        let item = this.#itemsMap.get ( itemObjId );
224
        item.isExpanded = ! item.isExpanded;
225
    }
226
227
    /**
228
    Mark the complete dictionary as expanded
229
    */
230
231
    expand ( ) {
232
        this.#expand ( this.#dictionary );
233
    }
234
235
    /**
236
    Mark the complete dictionary except the root item as not expanded
237
    */
238
239
    collapse ( ) {
240
        this.#dictionary.items.forEach (
241
            item => this.#collapse ( item )
242
        );
243
    }
244
245
}
246
247
/* ------------------------------------------------------------------------------------------------------------------------- */
248
/**
249
The one and only one instance of OsmSearchDictionary class
250
@type {OsmSearchDictionary}
251
*/
252
/* ------------------------------------------------------------------------------------------------------------------------- */
253
254
const theOsmSearchDictionary = new OsmSearchDictionary ( );
255
256
export default theOsmSearchDictionary;
257
258
/* --- End of file --------------------------------------------------------------------------------------------------------- */
259