Introduction

When users are reading a digital map, they expect different levels of detail (LoDs) depending on the scale. For example, they may want to see individual buildings when zooming in and see built-up areas when zooming out. That is why depicting geographical information is dependent on the scale (Müller et al. 1995; Weibel 1997). In order to prepare map data for different scales, a detailed map is generalized to generate coarser data for maps at smaller scales, which is known as map generalization. Mackaness et al. (2016) gave a taxonomy of generalization algorithms, including selection, simplification, and aggregation. Often, a multi-representation database (MRDB) is utilized to store map data of different scales, and the proper data is sent to clients on request (e.g., Hampe et al. 2004). As a result, the scale transition of a map is realized by switching between different LoDs. However, that strategy often brings large and discrete changes, which confuse users. In order to provide users with better experience of zooming, we propose to realize the scale transition with smooth changes. In other words, each object on the map should be changed smoothly when the scale changes. For example, a smooth way to simplify a polyline is to move some of the vertices to a straight line, and a smooth way to make a polygon disappear is to fade it out. Because all the objects are changed smoothly, users can keep track of their interested objects more easily. The technology to realize the smooth scale transition is known as continuous map generalization (CMG). Algorithms of CMG have been proposed to morph raster maps (e.g., Pantazis et al. 2009b, a), to morph polylines (e.g., Nöllenburg et al. 2008; Peng et al. 2013; Deng and Peng 2015; Li et al. 2017a, 2018), to generalize buildings (e.g., Li et al. 2017; Peng and Touya 2017; Touya and Dumont 2017), to transform road networks or river networks (e.g., Šuba et al. 2016; Chimani et al. 2014; Huang et al. 2017; Peng et al. 2012), and to morph administrative boundaries (e.g., Peng et al. 2016). Recently, Shen et al. (2020) proposed a method to progressively collapse rivers based on superpixels. Furthermore, CMG can be also used to simulate some temporal evolution of phenomena, for example, how a flooding submerges the land.

Area objects are important features on maps. When users zoom out, some area objects become too tiny to be seen, which results in visual clutter. The clutter can be avoided by generalizing the area objects. The generalization operators include merging (e.g., Haunert and Wolff 2010), amalgamating (e.g., Ware et al. 1995), aggregating (e.g., Peng and Touya 2017), splitting (e.g., Meijers et al. 2016), and collapsing (e.g., Haunert and Sester 2008). However, if zooming is realized by switching between some levels of map representations, large and discrete changes usually happen. This kind of changes may cause users to lose track of their area objects of interest (Van Kreveld, 2001). In order to solve this problem, we smoothly and simultaneously generalize the area objects. In our setting, each of the area objects has its semantic property, which is also called the class (e.g., lake, building, and grassland).

The main contribution of this paper is to generalize simultaneously, which is the first time that the simultaneity is explicitly proposed. Because of the simultaneity, each generalization operation has more time to take place and thus expands in more animation frames, which makes the generalization operation visually smoother. The reasoning is as follows, taking merging as an example. For zooming out, we wish to merge the relatively unimportant areas into their neighbors to form larger areas. In order to provide small and smooth changes, this paper merges a pair of areas by gradually expanding one (winner) over the other (loser). At the same time, the loser gradually adapts its color to the winner. However, if all the merging operations happen sequentially, then each operation has to be processed very fast because the map user wants to see the map at the target scale rather soon after applying a zooming. That is to say, each merging expansion may take place in only one frame, and users see only discrete changes. In contrast, if some merging operations happen simultaneously, then they can share their time duration, and each merging expansion can take place in many frames. As a result, users really see the smooth merging.

This paper is organized as follows. The “Related Work” section reviews some related work. Our methodology is presented in the “Methodology” section. We show a case study in the “Case Study” section. Finally, the “Concluding Remarks” section draws the conclusion and presents the future work.

Related Work

Merging, amalgamation, and aggregation are three popular operators of combining area objects. According to Shea and McMaster (1989), merging combines neighbor objects, which (visually) share their boundaries, into a single one, and the result has the same dimension as the merged objects. Amalgamation is different from merging in that it combines nearby objects into a single one. In contrast, aggregation often involves the change of dimension. For example, points are aggregated to become an area.

Both Su et al. (1997) and Sester (2005) used morphological operators (e.g., a dilation followed by an erosion) to amalgamate area objects, where the former article worked on raster data and the latter worked on vector data. Regnauld (2003) amalgamated area objects by merging, bridging, flooding, or sampling. Shen et al. (2019) amalgamated area objects based on the superpixel method of Achanta et al. (2012). Ware et al. (1995) amalgamated some pairs of objects based on the constrained Delaunay triangulation (CDT), where they introduced operators append merge, direct merge, and snap merge for rectangular objects, as well as adopt merge for natural objects. Ai and Zhang (2007) progressively aggregated building clusters, where they found the building clusters based on the CDT. Peng and Touya (2017) continuously aggregated buildings to built-up areas by bridging and growing the buildings. Touya and Dumont (2017) aggregated buildings by progressively covering them with blocks.

We have just briefly reviewed the related work of amalgamation and aggregation. In the remainder of this section, we will focus on merging because our research belongs to this topic.

Merging of Area Objects

Cheng and Li (2006), for a target area, proposed three choices of selecting a neighboring area to merge, i.e., the neighbor has the largest size, shares the longest boundary with the target area, or has the closest class to the target area. Thiemann and Sester (2018) proposed a chain of operators to generalize a land-cover map. In the chain of processing area objects, they integrated cleaning, dissolving, splitting, merging, reclassifying, and simplifying. Both Haunert and Wolff (2010) and Oehrlein and Haunert (2017) employed integer linear programs to merge area objects in order to find some optimal solutions when generating a map at a certain scale.

Gradual Merging of Area Objects

To provide the scale transition with small changes, van Oosterom (1995) proposed the generalized area partitioning (GAP) tree. In the tree, each leaf node represents a simple area on the map, and each of the other nodes represents a compound area, where a compound area contains some other areas. To build the tree, the least important area is found and merged into its most compatible neighbor. Correspondingly, the former’s node becomes a child of the latter’s node. This process repeats until the root node is found. Each level of the GAP tree corresponds to a scale of the map. As the changes between two neighboring levels of the tree are small, it is possible to realize the scale transition with small changes. Because that method works only on areas without gaps, Ai and van Oosterom (2002) made an extension to the GAP tree to allow gaps between areas. They identified gaps based on the CDT and filled the gaps to connect nearby areas. The topological GAP (tGAP) structure consists of a face tree and an edge tree (van Oosterom 2005). The aim of proposing the tGAP structure is to minimize the redundancy, where each vertex is recorded only once while it may be presented in many map representations of different scales. Peng et al. (2020b) tried to find an optimal sequence to merge area objects based on the A\({}^{\star }\) algorithm or an integer linear program. Their comparison, also including a greedy algorithm, showed that the A\({}^\star\) algorithm outperforms the two other methods in the aspects of minimizing the class changes and maximizing the area compactnesses. Šuba et al. (2016) continuously generalized a planar map of road network. In each step, they process the least important area object. Taking into account its local condition (e.g., no compatible neighbor at the same side of the road), they may take different decisions for the least important area object: increasing its importance, collapsing it, or merging it into an adjacent area.

To provide real smooth changes of zooming, van Oosterom and Meijers (2014) developed the concept of the space-scale cube (SSC). The bottom of the SSC is a detailed topographic map, then all the area objects extrude along the z-axis. In the SSC, an area on the map becomes a polyhedron, and the common boundary of two areas becomes a vertical wall. Whenever a generalization operation happens, the extrusions of the involved areas stop; then, the newly generated areas take over the place and start to extrude. On this basis, the map at any scale can be generated by slicing the SSC with a horizontal plane at a corresponding z-coordinate (e.g., Fig. 1). That is to say, the scale becomes the third dimension of the map in the SSC. Furthermore, they represented the smooth tGAP in the SSC. A typical example of the smooth generalization operation is that an area merges with another one by gradually expanding over the latter. In the SSC of the smooth tGAP, the wall starts to tilt when the expansion begins. To build such an SSC, Šuba et al. (2014) proposed three methods to merge a pair of areas in a gradual manner, namely the Single flat plane, the Zipper, and the Eater. Basically, the winner area gradually expands over the loser area. We will use the Eater because it works for all kinds of polygons, while the other two methods have their limitations for some cases. For example, the two other methods do not work for certain concave polygons. The principle of the Eater is as follows. First, the interior of the loser is triangulated with a CDT (see Fig. 2a). Second, the triangles are visited starting from the boundary between the winner and the loser: If there are triangles with two shared edges, then the visiting starts from the shared vertex of the two edges; otherwise, it starts from the shared edges. During visiting, the vertices of the triangles are assigned with increasing z-values, and the tilted triangles are generated, which become the boundaries of polyhedra in the SSC. When slicing the SSC with a horizontal plane, the eating process is presented as shown in Fig. 2b.

Fig. 1
figure 1

Maps can be obtained by slicing the SSC; taken from Meijers et al. (2020)

Fig. 2
figure 2

The principle of the Eater; taken from Šuba et al. (2014). (a) The space scale cube of a loser area. (b) The eating process

Merging Considering Semantic Properties

As mentioned in the “Introduction” section, each of the area objects has its semantic property (i.e., class). When we merge an area into another area, the semantic property of the former is changed to that of the latter. It is important not to cause too much change for two reasons. First, the generalized map should resemble the base map. Second, big changes cause users to lose track of their interested areas.

Van Oosterom and Schenkelaars’s (1995) greedy algorithm repeatedly merges the least important area with one of its neighbors. When choosing the neighbor, the algorithm considers the compatibility between the least important area and the neighbor, where the compatibility can be defined based on the semantic property. Haunert and Wolff (2010) defined distances between semantic properties and included those distances into the cost function of their integer linear program. Peng et al. (2020b) defined the semantic distance based on a tree of classes, which guarantees that the distance is a metric (see Fig. 3).

Fig. 3
figure 3

A way of defining distances between the classes; taken from Peng et al. (2020b)

Van Smaalen (2003 Section 4.4.3) mentioned the class-driven generalization, where if the two classes of two area objects are under the same super class, then the two area objects should be merged, and the new area object uses the super class. van Smaalen (2003 Section 4.5) suggested that the merging operation should also consider classes that co-occur spatially. He proposed the class adjacency index to measure if two classes are often adjacent; if so, the two objects, with the two classes, should be aggregated, and a composite class should be used.

Simultaneous Generalization Operators

Many methods of CMG naturally apply multiple generalization operators simultaneously. In morphing polylines, the points of the polylines are moved at the same time (e.g., Nöllenburg et al. 2008; Li et al. 2017a). Li et al. (2017) simultaneously generalized individual buildings. Peng and Touya (2017) and Touya and Dumont (2017) generalized buildings to built-up areas; however, there is no simple relationship between their intermediate-scale maps and their source maps. Therefore, all the intermediate-scale maps of buildings have to be sent from the server to the clients, which is network intensive.

Gradual Transformation in Web Environment

Based on the SSC, Meijers et al. (2020) explained the principles of implementing a web map of area objects. They showed how to request only a part of a large dataset of a vario-scale map. They made chunks of the SSC data so that they were able to send only the chunks relevant to users’ interested place. They showed how to efficiently slice the SSC to output a web map at a given scale using the GPU at the client side. In addition to slicing the SSC with a horizontal plane, they also sliced the SSC with a curly surface to have a locally more detailed map or with a tilted surface to have a perspective view. Huang et al. (2016) pointed out that the effort of implementing online maps had been spent mainly on preparing data on the server side. They studied the communication of map data between the server side and the client side. They proposed different strategies of assigning the work of processing map data according to the machine abilities of the clients (i.e., thin, medium, or thick client). Their implementation or option C supports gradual transformation of objects. For a zooming operation, that implementation continuously requests data from the server side and present them on the map until the map of the target scale is complete. Peng et al. (2020a) presented a tool to compare two web maps side by side. In order to allow users to easily access other map information, the tool presents a multi-scale raster layer as the background. Their example respectively used a vario-scale and a multi-scale vector layer as the foregrounds and compared between them.

Methodology

Figure 4 shows three different merging strategies. In Fig. 4a1a3, all the changes from a level to the next level are processed in one go, at a specific point. In Fig. 4b1b7, there is only one merging operation from a level to the next level, and the change is realized by an expanding animation (see Fig. 4b8). In Fig. 4c1c5, there can be many merging operations from a level to the next level, and each change is realized by an expanding animation (see Fig. 4c6). The first strategy often brings large and discrete changes (see for example from a1 to a2), which should be avoided. Both the second one and the third one have the ability to provide smooth changes. Comparing to the second strategy, the third one results in longer animation durations for some merging operations because the changes can share their animation durations.Footnote 1 The smooth changes are realized by slicing the space-scale cubes (SSCs) of Fig. 5 with a moving horizontal plane. For example, smooth animations of zooming out are obtained by slicing an SSC from bottom to top. In detail, Fig. 4b8 is obtained by slicing Fig. 5a at \(z= 50\). The details of slicing an SSC are illustrated in Meijers et al. (2020). The SSCs of Fig. 5 were built based on the Eater of Šuba et al. (2014). The content of an SSC is stored in an OBJ file, and the OBJ file can be visualized by software ParaView (see Fig. 5). In Fig. 5, the z-coordinates are 100 times of the state values in Fig. 4. We performed this multiplication for illustrative purpose only so that the contents of the SSC can be better observed.

Fig. 4
figure 4

A comparison of different scale-transition strategies. Each arrow inside the subfigures indicates a merging operation. The arrow in the right-hand side indicates the states of zooming out. Subfigures (a1a3), (b1b7), and (c1c5) represent the states at which the zooming may stop. Subfigures (a4), (b8), (c6), and (c7) are the map representations during the scale transition, where their corresponding states are indicated by the gray dots. The numbers are the IDs of the areas. Note that the colors of the smaller areas adapt to the colors of the larger areas during merging

Fig. 5
figure 5

In the left SSC, only one merging event is happening at a specific state (z-dimension), while in the right SSC multiple merging events may happen at the same state. (a) The SSC of the single merging of Fig. 4b1-b7. (b) The SSC of the simultaneous merging of Fig. 4c1-c7

The SSCs of Fig. 5a and b respectively serve for the single smooth merging (Fig. 4b1b7) and the simultaneous smooth merging (Fig. 4c1c5). The differences of the two SSCs result in the two different merging processes. For example, at \(z=50\) of Fig. 5a, there is only one polyhedron with the tilted face, hence there is only a pair of polygons merging in Fig. 4b8. In comparison, there are two polyhedra with tilted faces at \(z=50\) of Fig. 5b, and there are two pairs of polygons merging in Fig. 4c6. Note that the choices of selecting areas to merge are made in a pre-processing step and are stored in a database, before users start zooming on the map. Therefore, the choices are independent of users’ area objects of interest.

We define an event as a single generalization operation, such as merging an area with a neighbor. For example, Fig. 4b2 is obtained from Fig. 4b1 by processing one merging event. Similarly, Fig. 4c2 is obtained from Fig. 4c1 by processing two merging events. Note that two areas are neighbors if they share a common boundary with length larger than 0 (sharing a point does not make the two areas neighbors). We define a step as a set of events happening at the same animation duration, for example, from Fig. 4b1 to b2 or from Fig. 4c1 to c2. In our method, a step is completely processed before the next step takes place (all sequential). We define a state as the point when a step starts or finishes. For example, there are seven states in the merging sequence of Fig. 4b1b7 and five states in the merging sequence of Fig. 4c1c5 (i.e., states 0, 2, 4, 5, and 6). Note that the value of a state is also the total number of events processed so far.

There are two benefits of merging simultaneously. First, the simultaneity avoids unnatural zooming. Without the simultaneity, generalization operations that are processed all sequentially may result in no change at some locations in a zooming duration, which is unnatural (van Oosterom and Meijers 2014). Therefore, van Oosterom and Meijers (2014) suggested processing the generalization operations simultaneously, but no implementation, testing, or assessment of the idea was provided. Second, the simultaneity brings smoother zooming. When showing an animation zooming, we set 16 as the default value of the frames per second (FPS). This value is adequate to provide the visual continuity (Read and Meyer 2000, p. 24). If the merging operations happen sequentially instead of simultaneously, it is more likely that the time interval between two frames is larger than that between two states. Then, there is no animation of smooth merging shown at all. For example, if the consecutive frames are Fig. 4b1, b2, and b3, then users can only see discrete merging. In contrast, if the consecutive frames are Fig. 4c1, c7, and c2, then users can see one frame of ongoing expansion. As a result, the merging expansions are visually smoother when there are more merging operations processed simultaneously.

When merging simultaneously, we require that the area objects involved in different merging events of the same step must not be neighbors. This requirement makes the merging events independent from each other. In this way, it is easy for us to maintain the topology of the map. In order to realize the requirement, we block the pair of areas of a merging event, as well as their neighbors. These areas become blocked areas. The areas are free if they are not blocked yet. We develop a greedy algorithm to find the simultaneous merging events for each step in the “A greedy Algorithm” section. Then, we integrate the events into the tGAP database tables (section “Integrating the Simultaneous Events into the tGAP Database Tables”), followed by integrating the events into the SSC (section “Integrating the Simultaneous Events into the SSC”). In the “Snapping to a Valid State” section, we show how to snap the zooming to some valid states to avoid that the merging animation stops halfway. In the “Animation Duration of a Step” section, we define the animation duration of zooming from one state to another state. Note that the steps of the “A greedy Algorithm,” “Integrating the Simultaneous Events into the tGAP Database Tables,” and “Integrating the Simultaneous Events into the SSC” sections are done in a preprocess, and the final results are saved in some files. Then, the files are sent to the client on request when a user is browsing the map, where the steps of the “Snapping to a Valid State” and “Animation Duration of a Step” sections are done in real time.

A Greedy Algorithm

We use a greedy algorithm to find the simultaneous merging events for all steps. The merging events will be stored as records in the tGAP database tables (see Fig. 6). Some instances of the tables are shown in Table 1 of the “Integrating the Simultaneous Events into the tGAP Database Tables” section. To compose a merging event, we wish to merge the least important area into its most compatible neighbor. We define the importance and the compatibility according to van Putten and van Oosterom (1998). That is, the importance of an area is the multiplication of its size and its class weight. Currently, all the class weights are set to 1, which leads to that the smallest area is the least important. The compatibility value between a pair of areas is the multiplication of the common boundary’s length and the class similarity of the two areas. Appendix 1 shows our implementation of computing the weight values and the class similarities.

Fig. 6
figure 6

The Unified Modeling Language (UML) diagram of the classes stored in tGAP database tables. This diagram is a slightly improved version of Meijers (2011b, p. 159). In the face table, property pip_geometry stores a point (usually the center) in the face (polygon). The geometry of a face can be obtained by calling function getGeometry(). The face geometry is not stored because we want to avoid redundancy, as the edges already stored the sequences of the points

Table 1 Some columns of the face tables. Columns \(s_\text {low}\), \(s_\text {merge}\), and \(s_\text {high}\) show the states when the faces appear, when the faces start to disappear, and when the faces completely disappear. In table (b), the different values from table (a) are underlined. Column \(s_\text {merge}\) is not really stored in the database. We show the column so that it is easy to see the differences between the \(s_\text {low}\) values and the \(s_\text {merge}\) values

Figure 7 shows the flowchart of our greedy algorithm. The process starts with a detailed map of area objects. The map is denoted by \(M_s\), where state s is 0 at this point. Parameter \(r_\text {simul}\) specifies the proportion (i.e., percentage, when multiplied by 100) of area objects that are expected to be merged simultaneously. As a value of percentage, \(r_\text {simul}\) is in the range from \(0\) to \(100\%\), which means \(r_\text {simul} \in [0,1]\). We denote by \(|M_s|\) the number of \(M_s\)’s area objects. If there is more than one area (\(|M_s|>1\)), then the algorithm finds merging events for a new step. In other words, in each iteration when we have \(|M_s|>1\), a set of merging event for a step will be defined. We first compute the number of areas that we expect to merge by

$$\begin{aligned} n_\text {target} = \lceil r_\text {simul} \cdot |M_s| \rceil , \end{aligned}$$
(1)

where expression \(\lceil x \rceil\) returns the ceiling of x, which is the smallest integer greater than or equal to x. The ceiling function guarantees \(n_\text {target}\ge 1\). That is to say, the greedy algorithm finds at least one merging event for each step. When \(n_\text {target} > 1\), however, the greedy algorithm cannot always find \(n_\text {target}\) merging events because some areas may be blocked (also see Fig. 8). Therefore, we use variable \(n_\text {event}\) to represent the number of events that are actually found for a step.

Fig. 7
figure 7

The flowchart of our greedy algorithm. This algorithm finds the merging event for all the steps. The dashed rectangle marks the process of finding merging events for a single step

Fig. 8
figure 8

The process of finding simultaneous merging events for a single step. (a) From all the free areas, the least important one is selected to merge into its most compatible neighbor. Then, the two areas and the surrounding areas are blocked (marked by the crosses). (b) Next, the least important area from the remaining free areas is selected to merge with its most compatible neighbor, and the relevant areas are also blocked.

In Fig. 7, the dashed rectangle marks the process of finding merging events for a single step. If the process has not found \(n_\text {target}\) events yet (\(n_\text {event} < n_\text {target}\)) and there are still free areas, then the process continues looking for merging events. In detail, the greedy algorithm selects the least important area, \(a_\text {least}\), from the free areas. Then, the algorithm finds \(a_\text {least}\)’s most compatible neighbor \(a_\text {nbr}\).

  • If area \(a_\text {nbr}\) is also free, a merging event has been found, consisting of areas \(a_\text {least}\) and \(a_\text {nbr}\). Consequently, the number of events, \(n_\text {event}\), increases by 1. Then, \(a_\text {least}\), \(a_\text {nbr}\), and their neighbors are blocked (see Fig. 8a). Note that if an area shares only one vertex with \(a_\text {least}\) and/or \(a_\text {nbr}\), that area will not be blocked.

  • If area \(a_\text {nbr}\) is not free, then it must have been blocked because of the previously found events. In this case, we block \(a_\text {least}\) for now so that areas \(a_\text {least}\) and \(a_\text {nbr}\) may merge in the next step.

Now, let us move back to the start of finding merging events for a single step, that is, the condition “\(n_\text {event} < n_\text {target}\) and free areas exist.” If we have found \(n_\text {target}\) events or there is no free area anymore, then finding merging events of the step finishes. The greedy algorithm merges all the pairs of areas of the found events to generate new areas, frees all the blocked areas, increases state s by value \(n_\text {event}\), and creates map \(M_s\) based on the new areas and the freed areas. Then, finding merging events for the next step starts. This loop of finding completes when there is only one area left on the map (\(|M_s|=1\)). Figure 4c1c5 show a sequence of four merging steps obtained by our greedy algorithm, where simultaneous parameter \(r_\text {simul}\) is set to 0.3 (note that this is an extremely high value, used here to explain the principle in an artificial simple example).

The ideal situation to apply our method is that small areas distribute evenly and the areas do not have holes. The reason is as follows. We wish to use a rather large simultaneous parameter \(r_\text {simul}\) so that many events can share their merging durations. However, if the small areas do not distribute evenly, then some small areas will be blocked and kept while some larger areas will be merged, which is unreasonable. If an area has many holes, where each hole is filled with an area, then each step a hole merging into its surrounding area will forbid other holes to merge into it. This situation results in that some holes are merged until the scale is very small. A typical example is that a built-up area contains many buildings as holes.

Integrating the Simultaneous Events into the tGAP Database Tables

Meijers (2011b, p. 159) designed three tables to record the information of faces, edges, and face hierarchies, which together form a tGAP (see Fig. 6 the UML diagram of the tables). Note that both class Face and class Edge inherit the attributes from superclass tGAPTopolObject. His face table contains columns face_id, imp_low, imp_high, imp_own, feature_class, area, and mbr_geometry. We add columns state_low (\(s_\text {low}\)) and state_high (\(s_\text {high}\)) into the table so that it is easy to see when a face (i.e., an area object) should appear or disappear (the same is done also for the edge table). Values \(s_\text {low}\) and \(s_\text {high}\) of relevant areas in a step are assigned when all the pairs of areas are merged (see the step in Fig. 7). In detail, all those pairs of areas that are merged have \(s_\text {high} = s + n_\text {event}\), and the generated areas will have \(s_\text {low} = s + n_\text {event}\). Tables 1a and 1b shows the two new columns with column face_id. A face appears as a result of merging two faces during zooming out when the slicing arrives at the face’s low state. When the slicing arrives at its high state, the face should have been merged with another area. Comparing between the tables of single merging (Fig. 4b1b7) and simultaneous merging (Fig. 4c1c5), one can observe some differences of the values. For example, the \(s_\text {high}\) values of faces 1 and 2 are changed from 1 to 2 (see Table 1). Correspondingly, the \(s_\text {low}\) value of face 8 is changed from 1 to 2 (see Table 1). Note that the face IDs are defined in Fig. 4. Similarly to the face tables, the columns and records of both the edge table and the face-hierarchy table will be changed accordingly.

Integrating the Simultaneous Events into the SSC

Recall that we merge a pair of areas by expanding the winner over the loser. The Eater of Šuba et al. (2014) is used to triangulate the loser and to tilt the triangles. Then, the tilted triangles are integrated into the SSC (see Fig. 5) so that we can slice the SSC to achieve smooth merging. For the case of single merging, if a pair of areas have state-high value \(s_\text {high}\), then the merging animation always starts at state \(s_\text {merge}=s_\text {high}-1\) (see Table 1a). The less important area completely disappears at state \(s_\text {high}\). In the face table, a row will be added to record the new area, and its \(s_\text {low}\) value will be the previous \(s_\text {high}\) value. The new area takes over the combined place of the pair of areas. Take Fig. 4 as an example, area 1 is merged into area 2 (Fig. 4b1), and area 8 is generated to take over the combined place (Fig. 4b2). The tilted triangle is the one that spans from \(z= 0\) to \(z=100\) in Fig. 5a. In Table 1a, the \(s_\text {low}\) value of area 8 is 1, which is the \(s_\text {high}\) value of areas 1 and 2.

For the case of simultaneous merging, if a step consists of \(n_\text {event}\) events and the step finishes at state \(s_\text {high}\), then the step starts at state \(s_\text {merge}=s_\text {high} - n_\text {event}\). The reason is that if the \(n_\text {event}\) events would happen sequentially (i.e., single merging), then the first of the \(n_\text {event}\) events would start at state \(s_\text {high} - n_\text {event}\), the second would start at state \(s_\text {high} - n_\text {event} + 1\), and so on. Now that all the \(n_\text {event}\) events share their merging durations, all of them can start at state \(s_\text {high} - n_\text {event}\). As a result, each of the simultaneous events has more time to take place than the events would happen sequentially. In other words, for a merging step, each of the events has more time to take place if there are more simultaneous events.

In order to build the SSC for simultaneous merging, we need the \(s_\text {merge}\) value for each of the merging steps so that we know from which state the triangles of loser’s ceiling should be tilted. A simple way is to add a column, say, \(s_\text {merge}\) into the face table during generating the tGAP, as done in Table 1. Then, the states of starting merging can be recorded into the column. However, we would like to avoid unnecessary columns to save storage. Therefore, we compute \(s_\text {merge}\) values based on the \(s_\text {high}\) values on the fly when building the SSC. As an event involves two areas, the number of events finishing at state \(s_\text {high}\) can be calculated by:

$$\begin{aligned} n_\text {event} (s_\text {high}, \mathbf {s}_{\text {high}}) = \frac{\sum \limits _{s \in \mathbf {s}_{\text {high}}} \{s=s_\text {high}\}}{2} \end{aligned}$$
(2)

where vector \(\mathbf {s}_{\text {high}}\) denotes the values recorded in column \(s_\text {high}\) of the face table (e.g., Table 1b). Expression \(\{s=s_\text {high}\}\) returns 1 if the two values are equal and returns 0 otherwise. As illustrated before, the state at which the simultaneous merging starts can be computed by:

$$\begin{aligned} s_\text {merge} (s_\text {high}, \mathbf{s} _{\text {high}}) = s_\text {high} - n_\text {event} (s_\text {high}, \mathbf{s} _{\text {high}}) \end{aligned}$$
(3)

Take the case of Table 1b for example, we have \(\mathbf{s} _{\text {high}} = [2, 2, 4, 5, 4, 2, 2, 4, 6, 4, 5, 6]\), \(n_\text {event} (4, \mathbf{s} _{\text {high}}) = 2\), and \(s_\text {merge} (4, \mathbf{s} _{\text {high}}) = 2\). Therefore, there are two merging events finishing at state 4, i.e., the event of merging area 3 into area 8 and the event of merging area 5 into area 10 (also see Fig. 4c2 and c3). The merging animation takes place from state 2 to state 4. This merging can also be observed from the two tilted triangles spanning from \(z = 200\) to \(z = 400\) in Fig. 5b. In merging sequence of Fig. 4b1b7, the animation of merging area 3 into area 8 takes place from state 1 to state 2 (also see the tilted triangle spanning from \(z = 100\) to \(z = 200\) in Fig. 5a), and the animation of merging area 5 into area 10 takes place from state 3 to state 4 (also see the tilted triangle spanning from \(z = 300\) to \(z = 400\) in Fig. 5a). As a result, the animation duration of merging area 3 into area 8 of sequence Fig. 4c1c5 is almost twice as that of sequence Fig. 4b1b7. We say almost because the animation duration is also dependent on the state value of the map (see the “Animation Duration of a Step” section).

Snapping to a Valid State

For a zooming action based on the SSC, we always snap the map to a valid state. In this way, users will not see a merging operation stopping halfway. Take the sequence of Fig. 4c1c5 for example, the merging animation is allowed to stop at Fig. 4c1 or c2, but not at Fig. 4c6 or c7. In this example, state 1 is invalid because some merging operations have not completed. Here, the list of valid states is \(\mathbf{s} _{\text {valid}} = [0, 2, 4, 5, 6]\). In order to snap to one of the valid states, we have to communicate them to the client side. There are multiple options. The simplest one assumes that, the greedy algorithm can always find the \(n_\text {target}\) number of events in all steps. In that case, we just need to communicate the number of areas and the ratio \(r_\text {simul}\). However, this assumption may be incorrect in case of high value ratios (e.g., \(r_\mathrm {simul} > 0.01\)). We then have to communicate the valid states by sending them explicitly. Because this list may get rather large, we only send exceptions (see Appendix 2 for more details). As a result, the list of valid states \(\mathbf{s} _{\text {valid}}\) is generated on the client side.

According to how much a user has zoomed, the target scale, say, \(1:S_\text {t}\) can be computed. Huang et al. (2016) suggested that the average density of the base map should be preserved for a smaller-scale map. Their suggestion is based on the assumption that the area density of the base map is well designed, which is reasonable. We use variable \(A_\text {real}\) to denote the total areal size of all the area objects in reality. Then, the size on screen at scale \(1:S_\text {t}\) is \(A_\text {real} \big / S^2_\text {t}\). In order to keep the density, we require

$$\begin{aligned} \frac{N_\mathrm {b}}{A_\text {real} \big / S^2_\mathrm {b}} = \frac{N_\mathrm {b}-E_\mathrm {t}}{A_\text {real} \big / S^2_\mathrm {t}} \end{aligned}$$
(4)

where parameter \(N_\mathrm {b} = |M_0|\) is the number of areas on the base map, parameter \(S_\mathrm {b}\) is the scale denominator of the base map, and variable \(E_\mathrm {t}\) is the total number of events processed from the base map to the map at scale \(1:S_\mathrm {t}\) (in this case, an event is that an area is merged into another one). Eq. 4 yields:

$$\begin{aligned} E_\mathrm {t} = N_\mathrm {b} \left( 1-\frac{S^2_\mathrm {b}}{S^2_\mathrm {t}}\right) \end{aligned}$$
(5)

In our example of Fig. 4c1c5, if event number \(E_\mathrm {t} \le 0\), the base map should be presented; if \(E_\mathrm {t} \ge 6\), the map with the final single area should be presented. Otherwise, if \(0<E_\mathrm {t} < 6\), we snap event number \(E_\mathrm {t}\) to a value (measured in events) of list \(\mathbf{s} _{\text {valid}}\), which is denoted by \(E_\text {t,snap}\). The snapping also depends on if the map user is zooming in or out. For zooming in, \(E_\text {t,snap}\) is the closest value in \(\mathbf{s} _{\text {valid}}\) that is smaller than or equal to \(E_\text {t}\). For zooming out, \(E_\text {t,snap}\) is the closest value in \(\mathbf{s} _{\text {valid}}\) that is larger than or equal to \(E_\mathrm {t}\). This way of snapping prevents \(E_\text {t,snap}\) from being the same value before zooming; otherwise, the map will stand still if the map user zooms only a little bit. The scale denominator corresponding to event number \(E_\mathrm {t,snap}\) can be computed by

$$\begin{aligned} S_\text {t,snap} = S_\mathrm {b} \sqrt{\frac{N_\mathrm {b}}{N_\mathrm {b}-E_\text {t,snap}}} \end{aligned}$$
(6)

where this equation is an inverse function of Eq. 5. At the end of the zooming action, the map will snap to state \(s_\text {t,snap}\) at scale \(1:S_\text {t,snap}\). Note that state \(s_\text {t,snap}\) always has the same value as event number \(E_\text {t,snap}\).

Animation Duration of a Step

When users are zooming from a scale to another scale, some steps take place to change the state of the map accordingly. We define the zooming duration as the amount of animation time that the map reacts to one “rolling click” of the mouse wheel. The zooming duration often is the sum of the animation durations of several merging steps. The animation duration of each event depends on the number of events between the two states, the zooming factor of the scale, and the zooming duration. On the one hand, the animation duration should not be too short as then the animation will be too fast. On the other hand, if the animation takes too long, the map will not be interactive, and users will be “frustrated.” Meijers et al. (2020, Section 4.3) have introduced the zooming factor and the zooming duration. They allowed users to set the two parameters, which is also the case in our paper (see Fig. 9). This section formalizes the relationship of the animation duration, the zooming duration, the zooming factor, and the number of events. In a zooming duration, there can be many merging steps, no matter single merging or simultaneous merging. The formalization is based on the setting that a zooming duration is divided equally by its merging steps (Suba (2017, Section 6.7) showed some other possible settings). In other words, the steps happen sequentially and take the same amount of animation duration. Note that the steps from different zooming durations may have different animation durations.

Fig. 9
figure 9

Our panel of settings. Among others, one can set how much to zoom when scrolling the mouse wheel and set the zooming duration

Let \(N_\text {event}\) be the number of events happening in a zooming duration. Let \(n_\text {step}\) be the number of steps happening in the zooming duration. Let \(t_\text {single}\) be the animation duration of each of the steps, where each step consists of only one event. Let \(t_\text {simul}\) be the animation duration of each of the steps, where each step consists of at least one event. Then, we have

$$\begin{aligned} t_\text {simul} = t_\text {single} \frac{N_\text {event}}{n_\text {step}} \end{aligned}$$
(7)

As \(N_\text {event}\) is larger than or equal to \(n_\text {step}\), we have \(t_\text {simul} \ge t_\text {single}\). That is to say, when processing the merging events simultaneously, each step has more time to take place. The derivation of Eq. 7 is shown in Appendix 3.

Case Study

We have stored the result of the tGAP as a set of tables (see the “Integrating the Simultaneous Events into the tGAP Database Tables” section) in a PostgreSQL database. We have employed the Eater of Šuba et al. (2014), implemented in Python, to generate the elements (vertices, triangulated faces, and boundaries) of the SSC (van Oosterom et al. 2014) and saved these elements in an OBJ file.Footnote 2 When a user visits our website to access the map, some data will be sent to the client side. On the client side, the received data will be processed by a map viewer implemented in JavaScript. The processed data and some code based on WebGL (Web Graphics Library) are submitted to GPU so that the interactive map with smooth zooming can be output by slicing the SSC.

Figure 10 shows the topographic map of this case study.Footnote 3 The class codes and the rendering formulas are provided by the Dutch Kadaster.Footnote 4 Because the base scale is 1:10, 000, we have \(S_\mathrm {b} = 10{,}000\) for Eq. 6. The maximum value of event number \(E_\text {snap}\) is 13, 237 as there are in total 13, 238 areas. When we zoom out far enough so that \(E_\text {snap}\) reaches its maximum value, the scale denominator arrives at 1, 150, 565 according to Eq. 6. At that moment, all the areas are merged into one single area. In each step, we want to simultaneously merge some proportion of the areas. We tried three cases: 0.1%, 1%, and 10%. That is, simultaneous parameter \(r_{\mathrm {simul}}=0.001, 0.01, {\mathrm {and }} 0.1\) (see the “A greedy Algorithm” section), which are independent of the size of the map dataset. Fig. 11 shows two examples of our web map when simultaneous parameter \(r_\text {simul}=0.01\).Footnote 5

Fig. 10
figure 10

The data used in our case study. (a) A map of the Netherlands. (b) The topographic map used in our case study. There are 13,238 area objects. The map is for scale 1: 10,000

Fig. 11
figure 11

Two examples of our web map with different scales. (a) A part of the base map. The place is marked by the red dashed rectangle in Figure 10b. (b) An overview map. The place is marked by the blue dashed rectangle in Figure 10b. The overview map is generated from the base map by siultaneous merging with parameter rsimul = 0.01

Some statistics of the results when simultaneous parameter \(r_\text {simul}=0.001\), 0.01, or 0.1 are shown in Table 2. According to column \(N_\mathrm {step}\), the number of steps decreases when the simultaneous parameter increases. This is reasonable because more areas will be merged in each step. As explained in the “A greedy Algorithm” section, for each merging step we iteratively select the least important area and its most compatible neighbor to define a merging event; then, we block the two areas and their neighbors. Sometimes, a least important area is already blocked because of the previously found events. This situation happens 2, 714 times in total for all the steps when simultaneous parameter \(r_\text {simul}=0.01\) (see column \(N_\text {blocked}\) of Table 2).

Table 2 Some statistics when different simultaneous parameters area used. Column \(N_\mathrm {step}\) records the number of steps to transit from the base map to the map with a single area. Column \(N_\mathrm {blocked}\) records the number of times when the least important area was blocked. Column \(N_\mathrm {nbr\_blocked}\) records the number of times when the most compatible neighbor was blocked

Sometimes, although a least important area is free, its most compatible neighbor has been blocked because of the previously found events. This case happens 1, 383 times in total for all the steps when \(r_\text {simul}=0.01\) (see column \(n_\mathrm {nbr\_blocked}\) of Table2).

According to the statistics, we encounter more cases of the areas blocked when merging a larger proportion of the area objects. However, we can still reach our target number of events perfectly for settings of \(r_\text {simul}=0.01\) or \(r_\text {simul}=0.001\). Only when pushing beyond the limit (e.g., \(r_\text {simul}=0.1\)), we cannot reach the target number of events in a step (and we need correction information to compute the actual number of found events). When the target number of events cannot be met, one could also question the cartographic quality because there is hardly any free choice when generalizing.

As we can find the target numbers of merging events for all the steps when simultaneous parameter \(r_\mathrm {simul}= 0.001\) or 0.01, the corresponding exceptions lists are empty. When \(r_\text {simul}= 0.1\), the exception list is

$$\begin{aligned}{}[[1, 1304], [2, 1070], \dots , [77, 2]], \end{aligned}$$

which has 71 pairs of values. In reality, we would not use \(r_\text {simul}= 0.1\) (merging \(10\%\) of the current areas in every step) because it is an unrealistic high value. Using such a high value results in a multi-scale representation (because we have only a few valid states or scales), whereas we would like to have representations at nearly arbitrary scales.

Comparing to the map based on the single merging, the map based on the simultaneous merging indeed provides smoother zooming. We set zooming factor \(f_\text {zoom}=1\) and zooming duration \(t_\text {zoom}=1 s\) (see the “Animation Duration of a Step” section). The map based on the single merging gives the impression of discrete scale transition, where it is difficult to see a winner expands over a loser.Footnote 6 The reason is that the merging happens too fast, so the time for animation available is too short. This is also the case when we use simultaneous parameter \(r_\text {simul}= 0.001\).Footnote 7 We get the feeling of smooth merging when \(r_\mathrm {simul}= 0.01\).Footnote 8 When \(r_\mathrm {simul}= 0.1\), the smooth merging is already obvious.Footnote 9

Figure 12 shows a problem when we use simultaneous parameter \(r_\text {simul}= 0.1\). That is, some tiny and relatively unimportant areas stay until the scale is quite small, where they should be merged when the scale is larger. This problem has been mentioned in the “A greedy Algorithm” section. The reason of the problem is that there are many buildings in the middle of the figure. When the buildings share the same surrounding area, they become its holes. In each step, only one of the buildings can be merged into the surrounding area because of the blocking. In the meantime, the areas at other places of the map merge relatively fast because we expect to merge \(10\%\) of the areas in each step. Fortunately, we would not need to use such a big simultaneous parameter in reality.

Fig. 12
figure 12

Some tiny areas should be merged when the scale is larger, where the simultaneous parameter is 0.1

Concluding Remarks

Conclusion

This paper has examined the simultaneous processing of generalization operations, using the merging operation as a case study. The purpose of having simultaneous generalization operations is to provide smoother zooming experience later on (compared to the pure sequenced individual generalization events) so that users can better keep track of their interested objects. This paper developed a greedy algorithm to find simultaneous events of merging area objects. The simultaneous events were integrated into the tGAP and the SSC to nicely visualize the merging animations. To guarantee that the merging animations are completely shown while zooming, we managed to snap zooming operations to valid states. This paper also presented a recipe to define the animation duration of an event. According to our case study, the simultaneous merging indeed provides smoother zooming than the single merging.

Future Work

Many topics related to this research need to be studied further. Our case study with 13, 238 area objects demonstrated the efficiency of our prototype. In our case study, all the data of the SSC is stored in a single file because the tested map is not very big. The map will display only after the whole file is loaded. For a topographic map with much more objects, we are also developing a method that divides the SSC into many parts, and each part is stored in a file. A file will be dynamically loaded when the user is reading the relevant place and scale of the map. This strategy also allows progressive transfer of data (van Oosterom and Meijers 2014). Furthermore, a file at the client side will be removed to release main memory if the corresponding part of map is not browsed for a long time. With those functionalities, our prototype is able to handle a map with arbitrary number of area objects.

This paper used a greedy algorithm to find simultaneous merging events for each step. Alternatively, it is possible to define merging steps by selecting and combining some single-event steps of a sequence found by some existing methods (e.g., the greedy algorithm of van Oosterom (2005) or the A\(^{\star }\) algorithm of Peng et al. (2020b)).

Currently, the merging events distribute randomly on a map. If we are unlucky, there may be a lot of events happening in users’ focused region for a zooming duration, which may cause the users to lose track of their interested objects; for another zooming duration, there may be no event happening in the focused region at all. The strategy of blocking neighboring areas in our greedy algorithm already mitigates the problem. However, it may be even better if we explicitly distribute the merging events evenly, then the workload for a user to follow the events is consistent during the zooming. To this end, we could divide a map into many regions using a field-tree-like, multiple-level grid (van Putten and van Oosterom 1998) or using the road network. Then, we could find a certain number of events in each of the regions according to the regions’ sizes, which should result in an even distribution of events. Finally, we could compare our greedy algorithm and the algorithm considering even distribution.

Our current event consists of only the merging operation, it is also necessary to involve split operation because sometimes a merging operation results in an unnatural area. For example, it is weird to merge a long and thin area with one of the areas that are along it (see Haunert and Sester 2008). Therefore, such kind of long and thin areas should be split into several parts first. We may integrate a split method based on the straight skeleton of Haunert and Sester (2008) or the skeleton obtained from a CDT (Ai and van Oosterom 2002); Meijers et al. (2016). In addition to area features, we also need to support line features (e.g., roads, river, rail). In order to apply appropriate generalization operators for a certain scale, we need to extend and implement the framework to guide the generalization choices (Meijers et al. 2018).

To avoid clutter of vertices for zooming out, it is necessary to simplify the boundaries of the areas. Many existing methods could be integrated into our simultaneous paradigm. Meijers (2011a) proposed a method to simplify the boundaries simultaneously. The results are topologically safe. Another choice would be the method of Imai and Iri (1988), which is able to minimize the number of vertices for a given error threshold. One more choice would be to construct compatible triangulations (see Peng (2019), Chapter 3) for the two levels of topographic maps. In the SSC, we could build some tilted walls to connect the two levels of compatible triangulations. When we slice this SSC to animate a zooming action, the boundaries of the areas are morphed (moved smoothly and simultaneously) between a detailed representation and a coarse representation.

This paper develops the technique for smooth zooming based on simultaneous merging, and we hope that it allows map users to follow the zooming more easily. A future work is to examine how much can map users benefit from our technique. We will conduct some usability tests based on the experience of Section 6.7, Šuba (2017), and Midtbø and Nordvik (2007). Another future work is to find optimal simultaneous parameters for different kinds of datasets.