mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-20 13:23:59 +00:00
[editor] Mark businesse as disused/vacant
Signed-off-by: map-per <map-per@gmx.de>
This commit is contained in:
@@ -153,6 +153,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
private final Map<Metadata.MetadataType, View> mDetailsBlocks = new HashMap<>();
|
private final Map<Metadata.MetadataType, View> mDetailsBlocks = new HashMap<>();
|
||||||
private final Map<Metadata.MetadataType, View> mSocialMediaBlocks = new HashMap<>();
|
private final Map<Metadata.MetadataType, View> mSocialMediaBlocks = new HashMap<>();
|
||||||
private MaterialButton mReset;
|
private MaterialButton mReset;
|
||||||
|
private MaterialButton mDisused;
|
||||||
|
|
||||||
private EditorHostFragment mParent;
|
private EditorHostFragment mParent;
|
||||||
|
|
||||||
@@ -827,6 +828,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
osmInfo.setMovementMethod(LinkMovementMethod.getInstance());
|
osmInfo.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
mReset = view.findViewById(R.id.reset);
|
mReset = view.findViewById(R.id.reset);
|
||||||
mReset.setOnClickListener(this);
|
mReset.setOnClickListener(this);
|
||||||
|
mDisused = view.findViewById(R.id.disused);
|
||||||
|
mDisused.setOnClickListener(this);
|
||||||
|
|
||||||
mDetailsBlocks.put(Metadata.MetadataType.FMD_OPEN_HOURS, blockOpeningHours);
|
mDetailsBlocks.put(Metadata.MetadataType.FMD_OPEN_HOURS, blockOpeningHours);
|
||||||
mDetailsBlocks.put(Metadata.MetadataType.FMD_PHONE_NUMBER, blockPhone);
|
mDetailsBlocks.put(Metadata.MetadataType.FMD_PHONE_NUMBER, blockPhone);
|
||||||
@@ -894,6 +897,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
mParent.addLanguage();
|
mParent.addLanguage();
|
||||||
else if (id == R.id.reset)
|
else if (id == R.id.reset)
|
||||||
reset();
|
reset();
|
||||||
|
else if (id == R.id.disused)
|
||||||
|
placeDisused();
|
||||||
else if (id == R.id.block_outdoor_seating)
|
else if (id == R.id.block_outdoor_seating)
|
||||||
mOutdoorSeating.toggle();
|
mOutdoorSeating.toggle();
|
||||||
}
|
}
|
||||||
@@ -939,9 +944,12 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
if (mParent.addingNewObject())
|
if (mParent.addingNewObject())
|
||||||
{
|
{
|
||||||
UiUtils.hide(mReset);
|
UiUtils.hide(mReset);
|
||||||
|
UiUtils.hide(mDisused);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mDisused.setVisibility(Editor.nativeCanMarkPlaceAsDisused() ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
if (Editor.nativeIsMapObjectUploaded())
|
if (Editor.nativeIsMapObjectUploaded())
|
||||||
{
|
{
|
||||||
mReset.setText(R.string.editor_place_doesnt_exist);
|
mReset.setText(R.string.editor_place_doesnt_exist);
|
||||||
@@ -1014,6 +1022,19 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||||||
dialogFragment.setTextSaveListener(this::commitPlaceDoesntExists);
|
dialogFragment.setTextSaveListener(this::commitPlaceDoesntExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void placeDisused()
|
||||||
|
{
|
||||||
|
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
|
||||||
|
.setTitle(R.string.editor_mark_business_vacant_title)
|
||||||
|
.setMessage(R.string.editor_mark_business_vacant_description)
|
||||||
|
.setPositiveButton(R.string.editor_submit, (dlg, which) -> {
|
||||||
|
Editor.nativeMarkPlaceAsDisused();
|
||||||
|
mParent.processEditedFeatures();
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
private void commitPlaceDoesntExists(@NonNull String text)
|
private void commitPlaceDoesntExists(@NonNull String text)
|
||||||
{
|
{
|
||||||
Editor.nativePlaceDoesNotExist(text);
|
Editor.nativePlaceDoesNotExist(text);
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ public class EditorHostFragment
|
|||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processEditedFeatures()
|
public void processEditedFeatures()
|
||||||
{
|
{
|
||||||
if (OsmOAuth.isAuthorized())
|
if (OsmOAuth.isAuthorized())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -394,7 +394,8 @@
|
|||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/cv__more"
|
android:id="@+id/cv__more"
|
||||||
style="@style/MwmWidget.Editor.CardView">
|
style="@style/MwmWidget.Editor.CardView"
|
||||||
|
android:layout_marginBottom="@dimen/margin_base">
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -421,6 +422,17 @@
|
|||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/disused"
|
||||||
|
style="@style/MwmWidget.M3.Button.Secondary"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginBottom="@dimen/margin_quarter"
|
||||||
|
app:backgroundTint="?cardBackground"
|
||||||
|
android:textColor="@color/base_red"
|
||||||
|
app:strokeColor="@color/base_red"
|
||||||
|
android:text="@string/editor_business_vacant_button"/>
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/reset"
|
android:id="@+id/reset"
|
||||||
style="@style/MwmWidget.M3.Button.Secondary"
|
style="@style/MwmWidget.M3.Button.Secondary"
|
||||||
|
|||||||
@@ -551,6 +551,14 @@
|
|||||||
<string name="editor_place_doesnt_exist_description">Describe what the place looks like now to send an error note to the OpenStreetMap community</string>
|
<string name="editor_place_doesnt_exist_description">Describe what the place looks like now to send an error note to the OpenStreetMap community</string>
|
||||||
<!-- Error message for "Place doesn't exist" dialog when comment is empty -->
|
<!-- Error message for "Place doesn't exist" dialog when comment is empty -->
|
||||||
<string name="delete_place_empty_comment_error">Please indicate the reason for deleting the place</string>
|
<string name="delete_place_empty_comment_error">Please indicate the reason for deleting the place</string>
|
||||||
|
<!-- Button in the editor to mark business as vacant -->
|
||||||
|
<string name="editor_business_vacant_button">Business is vacant</string>
|
||||||
|
<!-- Title of confirmation dialog before marking business as vacant -->
|
||||||
|
<string name="editor_mark_business_vacant_title">Mark business as vacant</string>
|
||||||
|
<!-- Description in confirmation dialog before marking business as vacant -->
|
||||||
|
<string name="editor_mark_business_vacant_description">Use this if the business has moved out and the space is empty and ready for a new tenant.</string>
|
||||||
|
<!-- Submit change to OSM in the editor -->
|
||||||
|
<string name="editor_submit">Submit</string>
|
||||||
<!-- Phone number error message -->
|
<!-- Phone number error message -->
|
||||||
<string name="error_enter_correct_phone">Enter a valid phone number</string>
|
<string name="error_enter_correct_phone">Enter a valid phone number</string>
|
||||||
<string name="error_enter_correct_web">Enter a valid web address</string>
|
<string name="error_enter_correct_web">Enter a valid web address</string>
|
||||||
|
|||||||
@@ -277,6 +277,11 @@ JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsNameEd
|
|||||||
return g_editableMapObject.IsNameEditable();
|
return g_editableMapObject.IsNameEditable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeCanMarkPlaceAsDisused(JNIEnv * env, jclass clazz)
|
||||||
|
{
|
||||||
|
return g_editableMapObject.CanMarkPlaceAsDisused();
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsPointType(JNIEnv * env, jclass clazz)
|
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeIsPointType(JNIEnv * env, jclass clazz)
|
||||||
{
|
{
|
||||||
return g_editableMapObject.IsPointType();
|
return g_editableMapObject.IsPointType();
|
||||||
@@ -434,6 +439,11 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeRollbackMapO
|
|||||||
g_framework->NativeFramework()->RollBackChanges(g_editableMapObject.GetID());
|
g_framework->NativeFramework()->RollBackChanges(g_editableMapObject.GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeMarkPlaceAsDisused(JNIEnv * env, jclass clazz)
|
||||||
|
{
|
||||||
|
g_framework->NativeFramework()->MarkPlaceAsDisused(g_editableMapObject);
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetAllCreatableFeatureTypes(JNIEnv * env,
|
JNIEXPORT jobjectArray JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetAllCreatableFeatureTypes(JNIEnv * env,
|
||||||
jclass clazz,
|
jclass clazz,
|
||||||
jstring jLang)
|
jstring jLang)
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ public final class Editor
|
|||||||
|
|
||||||
public static native boolean nativeIsAddressEditable();
|
public static native boolean nativeIsAddressEditable();
|
||||||
public static native boolean nativeIsNameEditable();
|
public static native boolean nativeIsNameEditable();
|
||||||
|
public static native boolean nativeCanMarkPlaceAsDisused();
|
||||||
public static native boolean nativeIsPointType();
|
public static native boolean nativeIsPointType();
|
||||||
public static native boolean nativeIsBuilding();
|
public static native boolean nativeIsBuilding();
|
||||||
|
|
||||||
@@ -164,6 +165,7 @@ public final class Editor
|
|||||||
public static native void nativeCreateNote(String text);
|
public static native void nativeCreateNote(String text);
|
||||||
public static native void nativePlaceDoesNotExist(@NonNull String comment);
|
public static native void nativePlaceDoesNotExist(@NonNull String comment);
|
||||||
public static native void nativeRollbackMapObject();
|
public static native void nativeRollbackMapObject();
|
||||||
|
public static native void nativeMarkPlaceAsDisused();
|
||||||
public static native void nativeCreateStandaloneNote(double lat, double lon, String text);
|
public static native void nativeCreateStandaloneNote(double lat, double lon, String text);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ set(SRC
|
|||||||
xml_feature.cpp
|
xml_feature.cpp
|
||||||
xml_feature.hpp
|
xml_feature.hpp
|
||||||
yes_no_unknown.hpp
|
yes_no_unknown.hpp
|
||||||
|
keys_to_remove.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
omim_add_library(${PROJECT_NAME} ${SRC})
|
omim_add_library(${PROJECT_NAME} ${SRC})
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ std::string GetTypeForFeature(editor::XMLFeature const & node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (node.HasTag("disused:shop") || node.HasTag("disused:amenity"))
|
||||||
|
return "vacant business";
|
||||||
|
|
||||||
if (node.HasTag("addr:housenumber") || node.HasTag("addr:street") || node.HasTag("addr:postcode"))
|
if (node.HasTag("addr:housenumber") || node.HasTag("addr:street") || node.HasTag("addr:postcode"))
|
||||||
return "address";
|
return "address";
|
||||||
|
|
||||||
|
|||||||
133
libs/editor/keys_to_remove.hpp
Normal file
133
libs/editor/keys_to_remove.hpp
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
// Keys that should be removed when a place in OSM is replaced
|
||||||
|
// Copied from https://github.com/mnalis/StreetComplete-taginfo-categorize/blob/master/sc_to_remove.txt
|
||||||
|
// TODO(map-per) Check licence compatibility
|
||||||
|
inline constexpr std::string_view kKeysToRemove[] = {
|
||||||
|
"shop_?[1-9]?(:.*)?", "craft_?[1-9]?", "amenity_?[1-9]?", "club_?[1-9]?", "old_amenity",
|
||||||
|
"old_shop", "information", "leisure", "office_?[1-9]?", "tourism",
|
||||||
|
// popular shop=* / craft=* subkeys
|
||||||
|
"marketplace", "household", "swimming_pool", "laundry", "golf", "sports", "ice_cream",
|
||||||
|
"scooter", "music", "retail", "yes", "ticket", "newsagent", "lighting", "truck", "car_repair",
|
||||||
|
"car_parts", "video", "fuel", "farm", "car", "tractor", "hgv", "ski", "sculptor",
|
||||||
|
"hearing_aids", "surf", "photo", "boat", "gas", "kitchen", "anime", "builder", "hairdresser",
|
||||||
|
"security", "bakery", "bakehouse", "fishing", "doors", "kiosk", "market", "bathroom", "lamps",
|
||||||
|
"vacant", "insurance(:.*)?", "caravan", "gift", "bicycle", "bicycle_rental", "insulation",
|
||||||
|
"communication", "mall", "model", "empty", "wood", "hunting", "motorcycle", "trailer",
|
||||||
|
"camera", "water", "fireplace", "outdoor", "blacksmith", "electronics", "fan", "piercing",
|
||||||
|
"stationery", "sensory_friendly(:.*)?", "street_vendor",
|
||||||
|
// obsoleted information
|
||||||
|
"(demolished|abandoned|disused)(:(?!bui).+)?", "was:.*", "not:.*", "damage", "created_by",
|
||||||
|
"check_date", "opening_date", "last_checked", "checked_exists:date", "pharmacy_survey",
|
||||||
|
"old_ref", "update", "import_uuid", "review", "fixme:atp",
|
||||||
|
// classifications / links to external databases
|
||||||
|
"fhrs:.*", "old_fhrs:.*", "fvst:.*", "ncat", "nat_ref", "gnis:.*", "winkelnummer",
|
||||||
|
"type:FR:FINESS", "type:FR:APE", "kvl_hro:amenity", "ref:DK:cvr(:.*)?", "certifications?",
|
||||||
|
"transiscope", "opendata:type", "local_ref", "official_ref",
|
||||||
|
// names and identifications
|
||||||
|
"name_?[1-9]?(:.*)?", ".*_name_?[1-9]?(:.*)?", "noname", "branch(:.*)?", "brand(:.*)?",
|
||||||
|
"not:brand(:.*)?", "network(:.*)?", "operator(:.*)?", "operator_type", "ref", "ref:vatin",
|
||||||
|
"designation", "SEP:CLAVEESC", "identifier", "ref:FR:SIRET", "ref:FR:SIREN", "ref:FR:NAF",
|
||||||
|
"(old_)?ref:FR:prix-carburants",
|
||||||
|
// contacts
|
||||||
|
"contact_person", "contact(:.*)?", "phone(:.*)?", "phone_?[1-9]?", "emergency:phone",
|
||||||
|
"emergency_telephone_code",
|
||||||
|
"mobile", "fax", "facebook", "instagram", "twitter", "youtube", "telegram", "email",
|
||||||
|
"website_?[1-9]?(:.*)?", "app:.*", "ownership",
|
||||||
|
"url", "url:official", "source_ref:url", "owner",
|
||||||
|
// payments
|
||||||
|
"payment(:.*)?", "payment_multi_fee", "currency(:.*)?", "cash_withdrawal(:.*)?", "fee",
|
||||||
|
"charge", "charge_fee", "money_transfer", "donation:compensation", "paypoint",
|
||||||
|
// generic shop/craft attributes
|
||||||
|
"seasonal", "time", "opening_hours(:.*)?", "check_(in|out)", "wifi", "internet",
|
||||||
|
"internet_access(:.*)?", "second_hand", "self_service", "automated", "license:.*",
|
||||||
|
"bulk_purchase", ".*:covid19", "language:.*", "baby_feeding", "description(:.*)?",
|
||||||
|
"description[0-9]", "min_age", "max_age", "supermarket(:.*)?", "social_facility(:.*)?",
|
||||||
|
"functional", "trade", "wholesale", "sale", "smoking(:outside)?", "zero_waste", "origin",
|
||||||
|
"attraction", "strapline", "dog", "showroom", "toilets?(:.*)?", "sanitary_dump_station",
|
||||||
|
"changing_table(:.*)?", "wheelchair(.*)?", "blind", "company(:.*)?", "stroller", "walk-in",
|
||||||
|
"webshop", "operational_status.*", "status", "drive_through", "surveillance(:.*)?",
|
||||||
|
"outdoor_seating", "indoor_seating", "colour", "access_simple", "floor", "product_category",
|
||||||
|
"guide", "source_url", "category", "kids_area", "kids_area:indoor", "resort", "since", "state",
|
||||||
|
"temporary", "self_checkout", "audio_loop", "related_law(:.*)?", "official_status(:.*)?",
|
||||||
|
// food and drink details
|
||||||
|
"bar", "cafe", "coffee", "microroasting", "microbrewery", "brewery", "real_ale", "taproom",
|
||||||
|
"training", "distillery", "drink(:.*)?", "cocktails", "alcohol", "wine([:_].*)?",
|
||||||
|
"happy_hours", "diet:.*", "cuisine", "ethnic", "tasting", "breakfast", "lunch", "organic",
|
||||||
|
"produced_on_site", "restaurant", "food", "pastry", "pastry_shop", "product", "produce",
|
||||||
|
"chocolate", "fair_trade", "butcher", "reservation(:.*)?", "takeaway(:.*)?", "delivery(:.*)?",
|
||||||
|
"caterer", "real_fire", "flour_fortified", "highchair", "fast_food", "pub", "snack",
|
||||||
|
"confectionery", "drinking_water:refill",
|
||||||
|
// related to repair shops/crafts
|
||||||
|
"service(:.*)?", "motorcycle:.*", "repair", ".*:repair", "electronics_repair(:.*)?",
|
||||||
|
"workshop",
|
||||||
|
// shop=hairdresser, shop=clothes
|
||||||
|
"unisex", "male", "female", "gender", "gender_simple", "lgbtq(:.*)?", "gay", "female:signed",
|
||||||
|
"male:signed",
|
||||||
|
// healthcare
|
||||||
|
"healthcare(:.*)?", "healthcare_.*", "health", "health_.*", "medical_.*", "emergency_ward",
|
||||||
|
"facility(:.*)?", "activities", "healthcare_facility(:.*)?", "laboratory(:.*)?", "blood(:.*)?",
|
||||||
|
"blood_components", "infection(:.*)?", "disease(:.*)?", "covid19(:.*)?", "COVID_.*",
|
||||||
|
"CovidVaccineCenterId", "coronaquarantine", "hospital(:.*)?", "hospital_type_id",
|
||||||
|
"emergency_room", "sample_collection(:.*)?", "bed_count", "capacity:beds", "part_time_beds",
|
||||||
|
"personnel:count", "staff_count(:.*)?", "admin_staff", "doctors", "doctors_num", "nurses_num",
|
||||||
|
"counselling_type", "testing_centres", "toilets_number", "urgent_care", "vaccination",
|
||||||
|
"clinic", "hospital", "pharmacy", "alternative", "laboratory", "sample_collection",
|
||||||
|
"provided_for(:.*)?", "social_facility_for", "ambulance", "ward",
|
||||||
|
"HSE_(code|hgid|hgroup|region)", "collection_centre", "design", "AUTORIZATIE", "reg_id",
|
||||||
|
"post_addr", "scope", "ESTADO", "NIVSOCIO", "NO", "EMP_EST", "COD_HAB", "CLA_PERS", "CLA_PRES",
|
||||||
|
"snis_code:.*", "hfac_bed", "hfac_type", "nature", "moph_code", "IJSN:.*", "massgis:id",
|
||||||
|
"OGD-Stmk:.*", "paho:.*", "panchayath", "pbf_contract", "pcode", "pe:minsa:.*", "who:.*",
|
||||||
|
"pharmacy:category", "tactile_paving", "HF_(ID|TYPE|N_EN)", "RoadConn", "bin", "hiv(:.*)?",
|
||||||
|
// accommodation & layout
|
||||||
|
"rooms", "stars", "accommodation", "beds", "capacity(:persons)?", "laundry_service",
|
||||||
|
"guest_house",
|
||||||
|
// amenity=place_of_worship
|
||||||
|
"deanery", "subject:(wikidata|wikipedia|wikimedia_commons)", "church", "church:type",
|
||||||
|
// schools
|
||||||
|
"capacity:(pupils|teachers)", "grades", "population:pupils(:.*)?",
|
||||||
|
"school:(FR|gender|trust|type|type_idn)", "primary",
|
||||||
|
// clubs
|
||||||
|
"animal(_breeding|_training)?", "billiards(:.*)?", "board_game", "sport_1", "sport:boating",
|
||||||
|
"boat:type", "canoe(_rental|:service)?", "kayak(_rental|:service)?",
|
||||||
|
"sailboat(_rental|:service)?", "horse_riding", "rugby", "boules", "callsign", "card_games",
|
||||||
|
"car_service", "catastro:ref", "chess(:.*)?", "children", "climbing(:.*)?", "club(:.*)?",
|
||||||
|
"communication(:amateur_radio.*)", "community_centre:for", "dffr:network", "dormitory",
|
||||||
|
"education_for:ages", "electrified", "esperanto", "events_venue", "family", "federation",
|
||||||
|
"free_flying(:.*)?", "freemasonry(:.*)?", "free_refill", "gaelic_games(:.*)?", "membership",
|
||||||
|
"military_service", "model_aerodrome(:.*)?", "mode_of_organisation(:.*)?", "snowmobile",
|
||||||
|
"social_centre(:for)?", "source_dat", "tennis", "old_website", "organisation", "school_type",
|
||||||
|
"scout(:type)?", "fraternity", "live_music", "lockable", "playground(:theme)?", "nudism",
|
||||||
|
"music_genre", "length", "fire_station:type:FR", "cadet", "observatory:type", "tower:type",
|
||||||
|
"zoo", "shooting", "commons", "groomer", "group_only", "hazard", "identity", "interaction",
|
||||||
|
"logo", "maxheight", "provides", "regional", "scale", "site", "plots", "allotments",
|
||||||
|
"local_food", "monitoring:pedestrian", "recording:automated", "yacht", "background_music",
|
||||||
|
"url:spaceapi", "openfire",
|
||||||
|
// misc specific attributes
|
||||||
|
"clothes", "shoes", "tailor", "beauty", "tobacco", "carpenter", "furniture", "lottery",
|
||||||
|
"sport", "dispensing", "tailor:.*", "gambling", "material", "raw_material", "stonemason",
|
||||||
|
"studio", "scuba_diving(:.*)?", "polling_station", "collector", "books", "agrarian",
|
||||||
|
"musical_instrument", "massage", "parts", "post_office(:.*)?", "religion", "denomination",
|
||||||
|
"rental", ".*:rental", "tickets:.*", "public_transport", "goods_supply", "pet", "appliance",
|
||||||
|
"artwork_type", "charity", "company", "crop", "dry_cleaning", "factory", "feature",
|
||||||
|
"air_conditioning", "atm", "vending", "vending_machine", "recycling_type", "museum",
|
||||||
|
"license_classes", "dance:.*", "isced:level", "school", "preschool", "university",
|
||||||
|
"research_institution", "research", "member_of", "topic", "townhall:type", "parish", "police",
|
||||||
|
"government", "thw:(lv|rb|ltg)", "office", "administration", "administrative", "association",
|
||||||
|
"transport", "utility", "consulting", "Commercial", "commercial", "private", "taxi",
|
||||||
|
"admin_level", "official_status", "target", "liaison", "diplomatic(:.*)?", "embassy",
|
||||||
|
"consulate", "aeroway", "department", "faculty", "aerospace:product", "boundary", "population",
|
||||||
|
"diocese", "depot", "cargo", "function", "game", "party", "political_party.*",
|
||||||
|
"telecom(munication)?", "service_times", "kitchen:facilities", "it:(type|sales)",
|
||||||
|
"cannabis:cbd", "bath:type", "bath:(open_air|sand_bath)", "animal_boarding", "animal_shelter",
|
||||||
|
"mattress", "screen", "monitoring:weather", "public", "theatre", "culture", "library",
|
||||||
|
"cooperative(:.*)?", "winery", "curtain", "lawyer(:.*)?", "local_authority(:.*)?", "equipment",
|
||||||
|
"hackerspace",
|
||||||
|
"camp_site", "camping", "bbq", "static_caravans", "emergency(:.*)?", "evacuation_cent(er|re)",
|
||||||
|
"education", "engineering", "forestry", "foundation", "lawyer", "logistics", "military",
|
||||||
|
"community_centre", "bank", "operational", "users_(PLWD|boy|elderly|female|girl|men)",
|
||||||
|
"Comments?", "comments?", "entrance:(width|step_count|kerb:height)", "fenced", "motor_vehicle",
|
||||||
|
"shelter",
|
||||||
|
};
|
||||||
@@ -668,7 +668,7 @@ void Editor::UploadChanges(string const & oauthToken, ChangesetTags tags, Finish
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
// Add tags to XMLFeature
|
// Add tags to XMLFeature
|
||||||
UpdateXMLFeatureTags(feature, journal);
|
UpdateXMLFeatureTags(feature, journal, changeset);
|
||||||
|
|
||||||
// Upload XMLFeature to OSM
|
// Upload XMLFeature to OSM
|
||||||
LOG(LDEBUG, ("CREATE Feature (newEditor)", feature));
|
LOG(LDEBUG, ("CREATE Feature (newEditor)", feature));
|
||||||
@@ -686,7 +686,7 @@ void Editor::UploadChanges(string const & oauthToken, ChangesetTags tags, Finish
|
|||||||
XMLFeature feature = GetMatchingFeatureFromOSM(changeset, fti.m_object);
|
XMLFeature feature = GetMatchingFeatureFromOSM(changeset, fti.m_object);
|
||||||
|
|
||||||
// Update tags of XMLFeature
|
// Update tags of XMLFeature
|
||||||
UpdateXMLFeatureTags(feature, journal);
|
UpdateXMLFeatureTags(feature, journal, changeset);
|
||||||
|
|
||||||
// Upload XMLFeature to OSM
|
// Upload XMLFeature to OSM
|
||||||
LOG(LDEBUG, ("MODIFIED Feature (newEditor)", feature));
|
LOG(LDEBUG, ("MODIFIED Feature (newEditor)", feature));
|
||||||
@@ -1321,7 +1321,7 @@ bool Editor::IsFeatureUploadedImpl(FeaturesContainer const & features, MwmId con
|
|||||||
return info && info->m_uploadStatus == kUploaded;
|
return info && info->m_uploadStatus == kUploaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::UpdateXMLFeatureTags(editor::XMLFeature & feature, std::list<JournalEntry> const & journal)
|
void Editor::UpdateXMLFeatureTags(editor::XMLFeature & feature, std::list<JournalEntry> const & journal, ChangesetWrapper & changeset)
|
||||||
{
|
{
|
||||||
for (JournalEntry const & entry : journal)
|
for (JournalEntry const & entry : journal)
|
||||||
{
|
{
|
||||||
@@ -1335,6 +1335,13 @@ void Editor::UpdateXMLFeatureTags(editor::XMLFeature & feature, std::list<Journa
|
|||||||
}
|
}
|
||||||
case JournalEntryType::ObjectCreated: break;
|
case JournalEntryType::ObjectCreated: break;
|
||||||
case JournalEntryType::LegacyObject: ASSERT_FAIL(("Legacy Objects can not be edited with the new editor")); break;
|
case JournalEntryType::LegacyObject: ASSERT_FAIL(("Legacy Objects can not be edited with the new editor")); break;
|
||||||
|
case JournalEntryType::BusinessReplacement:
|
||||||
|
{
|
||||||
|
BusinessReplacementData const & businessReplacementData = std::get<BusinessReplacementData>(entry.data);
|
||||||
|
feature.OSMBusinessReplacement(businessReplacementData.old_type, businessReplacementData.new_type);
|
||||||
|
changeset.AddChangesetTag("info:place_marked_as_disused", "yes");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "editor/changeset_wrapper.hpp"
|
||||||
#include "editor/config_loader.hpp"
|
#include "editor/config_loader.hpp"
|
||||||
#include "editor/editor_config.hpp"
|
#include "editor/editor_config.hpp"
|
||||||
#include "editor/editor_notes.hpp"
|
#include "editor/editor_notes.hpp"
|
||||||
@@ -241,7 +242,7 @@ private:
|
|||||||
|
|
||||||
static bool IsFeatureUploadedImpl(FeaturesContainer const & features, MwmId const & mwmId, uint32_t index);
|
static bool IsFeatureUploadedImpl(FeaturesContainer const & features, MwmId const & mwmId, uint32_t index);
|
||||||
|
|
||||||
void UpdateXMLFeatureTags(editor::XMLFeature & feature, std::list<JournalEntry> const & journal);
|
static void UpdateXMLFeatureTags(editor::XMLFeature & feature, std::list<JournalEntry> const & journal, ChangesetWrapper & changeset);
|
||||||
|
|
||||||
/// Deleted, edited and created features.
|
/// Deleted, edited and created features.
|
||||||
base::AtomicSharedPtr<FeaturesContainer> m_features;
|
base::AtomicSharedPtr<FeaturesContainer> m_features;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "editor/xml_feature.hpp"
|
#include "editor/xml_feature.hpp"
|
||||||
|
#include "editor/keys_to_remove.hpp"
|
||||||
|
|
||||||
#include "indexer/classificator.hpp"
|
#include "indexer/classificator.hpp"
|
||||||
#include "indexer/editable_map_object.hpp"
|
#include "indexer/editable_map_object.hpp"
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
#include "base/timer.hpp"
|
#include "base/timer.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <regex>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -502,6 +504,29 @@ osm::EditJournal XMLFeature::GetEditJournal() const
|
|||||||
entry.data = legacyObjData;
|
entry.data = legacyObjData;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case osm::JournalEntryType::BusinessReplacement:
|
||||||
|
{
|
||||||
|
osm::BusinessReplacementData businessReplacementData;
|
||||||
|
|
||||||
|
// Old Feature Type
|
||||||
|
std::string old_strType = getAttribute(xmlData, "old_type");
|
||||||
|
if (old_strType.empty())
|
||||||
|
MYTHROW(editor::InvalidJournalEntry, ("Old Feature type is empty"));
|
||||||
|
businessReplacementData.old_type = classif().GetTypeByReadableObjectName(old_strType);
|
||||||
|
if (businessReplacementData.old_type == IndexAndTypeMapping::INVALID_TYPE)
|
||||||
|
MYTHROW(editor::InvalidJournalEntry, ("Invalid old Feature Type:", old_strType));
|
||||||
|
|
||||||
|
// New Feature Type
|
||||||
|
std::string new_strType = getAttribute(xmlData, "new_type");
|
||||||
|
if (new_strType.empty())
|
||||||
|
MYTHROW(editor::InvalidJournalEntry, ("New Feature type is empty"));
|
||||||
|
businessReplacementData.new_type = classif().GetTypeByReadableObjectName(new_strType);
|
||||||
|
if (businessReplacementData.new_type == IndexAndTypeMapping::INVALID_TYPE)
|
||||||
|
MYTHROW(editor::InvalidJournalEntry, ("Invalid new Feature Type:", new_strType));
|
||||||
|
|
||||||
|
entry.data = businessReplacementData;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isHistory)
|
if (isHistory)
|
||||||
journal.AddJournalHistoryEntry(entry);
|
journal.AddJournalHistoryEntry(entry);
|
||||||
@@ -572,6 +597,13 @@ void XMLFeature::SetEditJournal(osm::EditJournal const & journal)
|
|||||||
xmlData.append_attribute("version") = legacyObjData.version.data();
|
xmlData.append_attribute("version") = legacyObjData.version.data();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case osm::JournalEntryType::BusinessReplacement:
|
||||||
|
{
|
||||||
|
osm::BusinessReplacementData const & businessReplacementData = std::get<osm::BusinessReplacementData>(entry.data);
|
||||||
|
xmlData.append_attribute("old_type") = classif().GetReadableObjectName(businessReplacementData.old_type).data();
|
||||||
|
xmlData.append_attribute("new_type") = classif().GetReadableObjectName(businessReplacementData.new_type).data();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -675,6 +707,49 @@ void XMLFeature::UpdateOSMTag(std::string_view key, std::string_view value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XMLFeature::OSMBusinessReplacement(uint32_t old_type, uint32_t new_type)
|
||||||
|
{
|
||||||
|
std::string name = GetTagValue("name");
|
||||||
|
|
||||||
|
// Remove OSM tags using the list from keys_to_remove.hpp
|
||||||
|
std::string regexPattern;
|
||||||
|
|
||||||
|
for (auto const & key : kKeysToRemove)
|
||||||
|
{
|
||||||
|
if (!regexPattern.empty())
|
||||||
|
regexPattern.append("|");
|
||||||
|
regexPattern.append(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::regex regex(regexPattern);
|
||||||
|
|
||||||
|
ForEachTag([& regex, this](std::string_view key, std::string_view /*value*/)
|
||||||
|
{
|
||||||
|
if (std::regex_search(key.begin(), key.end(), regex))
|
||||||
|
RemoveTag(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (classif().GetReadableObjectName(new_type) == "disusedbusiness")
|
||||||
|
{
|
||||||
|
// Mark as 'disused'
|
||||||
|
string const strOldType = classif().GetReadableObjectName(old_type);
|
||||||
|
strings::SimpleTokenizer iter(strOldType, "-");
|
||||||
|
string_view const key = *iter;
|
||||||
|
if (++iter)
|
||||||
|
SetTagValue("disused:" + std::string(key), *iter);
|
||||||
|
else
|
||||||
|
SetTagValue("disused:" + std::string(key), "yes");
|
||||||
|
|
||||||
|
SetTagValue("old_name", name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add new category tag
|
||||||
|
ASSERT_FAIL("Only marking places as 'disused' is implemented yet. "
|
||||||
|
"Wrong new_type: " + classif().GetReadableObjectName(new_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
string XMLFeature::GetAttribute(string const & key) const
|
string XMLFeature::GetAttribute(string const & key) const
|
||||||
{
|
{
|
||||||
return GetRootNode().attribute(key.data()).value();
|
return GetRootNode().attribute(key.data()).value();
|
||||||
|
|||||||
@@ -187,6 +187,8 @@ public:
|
|||||||
|
|
||||||
/// Wrapper for SetTagValue and RemoveTag, avoids duplication for similar alternative osm tags
|
/// Wrapper for SetTagValue and RemoveTag, avoids duplication for similar alternative osm tags
|
||||||
void UpdateOSMTag(std::string_view key, std::string_view value);
|
void UpdateOSMTag(std::string_view key, std::string_view value);
|
||||||
|
/// Replace an old business with a new business
|
||||||
|
void OSMBusinessReplacement(uint32_t old_type, uint32_t new_type);
|
||||||
|
|
||||||
std::string GetAttribute(std::string const & key) const;
|
std::string GetAttribute(std::string const & key) const;
|
||||||
void SetAttribute(std::string const & key, std::string const & value);
|
void SetAttribute(std::string const & key, std::string const & value);
|
||||||
|
|||||||
@@ -41,6 +41,13 @@ void EditJournal::MarkAsCreated(uint32_t type, feature::GeomType geomType, m2::P
|
|||||||
AddJournalEntry({JournalEntryType::ObjectCreated, time(nullptr), osm::ObjCreateData{type, geomType, mercator}});
|
AddJournalEntry({JournalEntryType::ObjectCreated, time(nullptr), osm::ObjCreateData{type, geomType, mercator}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditJournal::AddBusinessReplacement(uint32_t old_type, uint32_t new_type)
|
||||||
|
{
|
||||||
|
LOG(LDEBUG, ("Business of type ", classif().GetReadableObjectName(old_type),
|
||||||
|
" was replaced by a ", classif().GetReadableObjectName(new_type)));
|
||||||
|
AddJournalEntry({JournalEntryType::BusinessReplacement, time(nullptr), osm::BusinessReplacementData{old_type, new_type}});
|
||||||
|
}
|
||||||
|
|
||||||
void EditJournal::AddJournalEntry(JournalEntry entry)
|
void EditJournal::AddJournalEntry(JournalEntry entry)
|
||||||
{
|
{
|
||||||
m_journal.push_back(std::move(entry));
|
m_journal.push_back(std::move(entry));
|
||||||
@@ -103,6 +110,15 @@ std::string EditJournal::ToString(osm::JournalEntry const & journalEntry)
|
|||||||
LegacyObjData const & legacyObjData = std::get<LegacyObjData>(journalEntry.data);
|
LegacyObjData const & legacyObjData = std::get<LegacyObjData>(journalEntry.data);
|
||||||
return ToString(journalEntry.journalEntryType).append(": version=\"").append(legacyObjData.version).append("\"");
|
return ToString(journalEntry.journalEntryType).append(": version=\"").append(legacyObjData.version).append("\"");
|
||||||
}
|
}
|
||||||
|
case osm::JournalEntryType::BusinessReplacement:
|
||||||
|
{
|
||||||
|
BusinessReplacementData const & businessReplacementData = std::get<BusinessReplacementData>(journalEntry.data);
|
||||||
|
return ToString(journalEntry.journalEntryType)
|
||||||
|
.append(": Category changed from ")
|
||||||
|
.append(classif().GetReadableObjectName(businessReplacementData.old_type))
|
||||||
|
.append(" to ")
|
||||||
|
.append(classif().GetReadableObjectName(businessReplacementData.new_type));
|
||||||
|
}
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,6 +130,7 @@ std::string EditJournal::ToString(osm::JournalEntryType journalEntryType)
|
|||||||
case osm::JournalEntryType::TagModification: return "TagModification";
|
case osm::JournalEntryType::TagModification: return "TagModification";
|
||||||
case osm::JournalEntryType::ObjectCreated: return "ObjectCreated";
|
case osm::JournalEntryType::ObjectCreated: return "ObjectCreated";
|
||||||
case osm::JournalEntryType::LegacyObject: return "LegacyObject";
|
case osm::JournalEntryType::LegacyObject: return "LegacyObject";
|
||||||
|
case osm::JournalEntryType::BusinessReplacement: return "BusinessReplacement";
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,6 +143,8 @@ std::optional<JournalEntryType> EditJournal::TypeFromString(std::string const &
|
|||||||
return JournalEntryType::ObjectCreated;
|
return JournalEntryType::ObjectCreated;
|
||||||
else if (entryType == "LegacyObject")
|
else if (entryType == "LegacyObject")
|
||||||
return JournalEntryType::LegacyObject;
|
return JournalEntryType::LegacyObject;
|
||||||
|
else if (entryType == "BusinessReplacement")
|
||||||
|
return JournalEntryType::BusinessReplacement;
|
||||||
else
|
else
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ enum class JournalEntryType
|
|||||||
TagModification,
|
TagModification,
|
||||||
ObjectCreated,
|
ObjectCreated,
|
||||||
LegacyObject, // object without full journal history, used for transition to new editor
|
LegacyObject, // object without full journal history, used for transition to new editor
|
||||||
|
BusinessReplacement,
|
||||||
// Possible future values: ObjectDeleted, ObjectDisused, ObjectNotDisused, LocationChanged, FeatureTypeChanged
|
// Possible future values: ObjectDeleted, ObjectDisused, ObjectNotDisused, LocationChanged, FeatureTypeChanged
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,11 +39,17 @@ struct LegacyObjData
|
|||||||
std::string version;
|
std::string version;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BusinessReplacementData
|
||||||
|
{
|
||||||
|
uint32_t old_type;
|
||||||
|
uint32_t new_type;
|
||||||
|
};
|
||||||
|
|
||||||
struct JournalEntry
|
struct JournalEntry
|
||||||
{
|
{
|
||||||
JournalEntryType journalEntryType = JournalEntryType::TagModification;
|
JournalEntryType journalEntryType = JournalEntryType::TagModification;
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
std::variant<TagModData, ObjCreateData, LegacyObjData> data;
|
std::variant<TagModData, ObjCreateData, LegacyObjData, BusinessReplacementData> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Used to determine whether existing OSM object should be updated or new one created
|
/// Used to determine whether existing OSM object should be updated or new one created
|
||||||
@@ -69,6 +76,9 @@ public:
|
|||||||
/// Log object creation in the journal
|
/// Log object creation in the journal
|
||||||
void MarkAsCreated(uint32_t type, feature::GeomType geomType, m2::PointD mercator);
|
void MarkAsCreated(uint32_t type, feature::GeomType geomType, m2::PointD mercator);
|
||||||
|
|
||||||
|
/// Log business replacement in the journal
|
||||||
|
void AddBusinessReplacement(uint32_t old_type, uint32_t new_type);
|
||||||
|
|
||||||
void AddJournalEntry(JournalEntry entry);
|
void AddJournalEntry(JournalEntry entry);
|
||||||
|
|
||||||
/// Clear Journal and move content to journalHistory, used after upload to OSM
|
/// Clear Journal and move content to journalHistory, used after upload to OSM
|
||||||
|
|||||||
@@ -87,6 +87,29 @@ vector<MapObject::MetadataID> EditableMapObject::GetEditableProperties() const
|
|||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EditableMapObject::CanMarkPlaceAsDisused() const
|
||||||
|
{
|
||||||
|
auto types = GetTypes();
|
||||||
|
types.SortBySpec();
|
||||||
|
uint32_t mainType = *types.begin();
|
||||||
|
std::string mainTypeStr = classif().GetReadableObjectName(mainType);
|
||||||
|
|
||||||
|
std::vector<string_view> typePrefixes = {
|
||||||
|
"shop",
|
||||||
|
"amenity-restaurant",
|
||||||
|
"amenity-fast_food",
|
||||||
|
"amenity-cafe",
|
||||||
|
"amenity-pub",
|
||||||
|
"amenity-bar",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto const & typePrefix : typePrefixes)
|
||||||
|
if (mainTypeStr.starts_with(typePrefix))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
NamesDataSource EditableMapObject::GetNamesDataSource()
|
NamesDataSource EditableMapObject::GetNamesDataSource()
|
||||||
{
|
{
|
||||||
auto const mwmInfo = GetID().m_mwmId.GetInfo();
|
auto const mwmInfo = GetID().m_mwmId.GetInfo();
|
||||||
@@ -656,6 +679,16 @@ void EditableMapObject::MarkAsCreated(uint32_t type, feature::GeomType geomType,
|
|||||||
m_journal.MarkAsCreated(type, geomType, std::move(mercator));
|
m_journal.MarkAsCreated(type, geomType, std::move(mercator));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditableMapObject::MarkAsDisused()
|
||||||
|
{
|
||||||
|
auto types = GetTypes();
|
||||||
|
types.SortBySpec();
|
||||||
|
uint32_t old_type = *types.begin();
|
||||||
|
uint32_t new_type = classif().GetTypeByReadableObjectName("disusedbusiness");
|
||||||
|
ApplyBusinessReplacement(new_type);
|
||||||
|
m_journal.AddBusinessReplacement(old_type, new_type);
|
||||||
|
}
|
||||||
|
|
||||||
void EditableMapObject::ClearJournal()
|
void EditableMapObject::ClearJournal()
|
||||||
{
|
{
|
||||||
m_journal.Clear();
|
m_journal.Clear();
|
||||||
@@ -673,7 +706,7 @@ void EditableMapObject::ApplyEditsFromJournal(EditJournal const & editJournal)
|
|||||||
void EditableMapObject::ApplyJournalEntry(JournalEntry const & entry)
|
void EditableMapObject::ApplyJournalEntry(JournalEntry const & entry)
|
||||||
{
|
{
|
||||||
LOG(LDEBUG, ("Applying Journal Entry: ", osm::EditJournal::ToString(entry)));
|
LOG(LDEBUG, ("Applying Journal Entry: ", osm::EditJournal::ToString(entry)));
|
||||||
// Todo
|
|
||||||
switch (entry.journalEntryType)
|
switch (entry.journalEntryType)
|
||||||
{
|
{
|
||||||
case JournalEntryType::TagModification:
|
case JournalEntryType::TagModification:
|
||||||
@@ -760,6 +793,12 @@ void EditableMapObject::ApplyJournalEntry(JournalEntry const & entry)
|
|||||||
ASSERT_FAIL(("Legacy Objects can not be loaded from Journal"));
|
ASSERT_FAIL(("Legacy Objects can not be loaded from Journal"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case JournalEntryType::BusinessReplacement:
|
||||||
|
{
|
||||||
|
BusinessReplacementData const & businessReplacementData = std::get<BusinessReplacementData>(entry.data);
|
||||||
|
ApplyBusinessReplacement(businessReplacementData.new_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,6 +898,47 @@ void EditableMapObject::LogDiffInJournal(EditableMapObject const & unedited_emo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditableMapObject::ApplyBusinessReplacement(uint32_t new_type)
|
||||||
|
{
|
||||||
|
// Types
|
||||||
|
feature::TypesHolder new_feature_types;
|
||||||
|
|
||||||
|
new_feature_types.Add(new_type); // Update feature type
|
||||||
|
|
||||||
|
std::string wheelchairType = feature::GetReadableWheelchairType(m_types);
|
||||||
|
if (!wheelchairType.empty())
|
||||||
|
new_feature_types.SafeAdd(classif().GetTypeByReadableObjectName(wheelchairType));
|
||||||
|
|
||||||
|
std::vector<uint32_t> const buildingTypes = ftypes::IsBuildingChecker::Instance().GetTypes();
|
||||||
|
for(uint32_t const & type : buildingTypes)
|
||||||
|
if (m_types.Has(type))
|
||||||
|
new_feature_types.SafeAdd(type);
|
||||||
|
|
||||||
|
m_types = new_feature_types;
|
||||||
|
|
||||||
|
// Names
|
||||||
|
m_name.Clear();
|
||||||
|
|
||||||
|
// Metadata
|
||||||
|
feature::Metadata new_metadata;
|
||||||
|
|
||||||
|
constexpr MetadataID metadataToKeep[] = {
|
||||||
|
MetadataID::FMD_WHEELCHAIR,
|
||||||
|
MetadataID::FMD_POSTCODE,
|
||||||
|
MetadataID::FMD_LEVEL,
|
||||||
|
MetadataID::FMD_ELE,
|
||||||
|
MetadataID::FMD_HEIGHT,
|
||||||
|
MetadataID::FMD_MIN_HEIGHT,
|
||||||
|
MetadataID::FMD_BUILDING_LEVELS,
|
||||||
|
MetadataID::FMD_BUILDING_MIN_LEVEL
|
||||||
|
};
|
||||||
|
|
||||||
|
for(MetadataID const & metadataID : metadataToKeep)
|
||||||
|
new_metadata.Set(metadataID, std::string(m_metadata.Get(metadataID)));
|
||||||
|
|
||||||
|
m_metadata = new_metadata;
|
||||||
|
}
|
||||||
|
|
||||||
bool AreObjectsEqualIgnoringStreet(EditableMapObject const & lhs, EditableMapObject const & rhs)
|
bool AreObjectsEqualIgnoringStreet(EditableMapObject const & lhs, EditableMapObject const & rhs)
|
||||||
{
|
{
|
||||||
feature::TypesHolder const & lhsTypes = lhs.GetTypes();
|
feature::TypesHolder const & lhsTypes = lhs.GetTypes();
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ public:
|
|||||||
/// All store/load/valid operations will be via MetadataEntryIFace interface instead of switch-case.
|
/// All store/load/valid operations will be via MetadataEntryIFace interface instead of switch-case.
|
||||||
std::vector<MetadataID> GetEditableProperties() const;
|
std::vector<MetadataID> GetEditableProperties() const;
|
||||||
|
|
||||||
|
bool CanMarkPlaceAsDisused() const;
|
||||||
|
|
||||||
/// See comment for NamesDataSource class.
|
/// See comment for NamesDataSource class.
|
||||||
NamesDataSource GetNamesDataSource();
|
NamesDataSource GetNamesDataSource();
|
||||||
LocalizedStreet const & GetStreet() const;
|
LocalizedStreet const & GetStreet() const;
|
||||||
@@ -141,11 +143,15 @@ public:
|
|||||||
void SetJournal(EditJournal && editJournal);
|
void SetJournal(EditJournal && editJournal);
|
||||||
EditingLifecycle GetEditingLifecycle() const;
|
EditingLifecycle GetEditingLifecycle() const;
|
||||||
void MarkAsCreated(uint32_t type, feature::GeomType geomType, m2::PointD mercator);
|
void MarkAsCreated(uint32_t type, feature::GeomType geomType, m2::PointD mercator);
|
||||||
|
void MarkAsDisused();
|
||||||
void ClearJournal();
|
void ClearJournal();
|
||||||
void ApplyEditsFromJournal(EditJournal const & journal);
|
void ApplyEditsFromJournal(EditJournal const & journal);
|
||||||
void ApplyJournalEntry(JournalEntry const & entry);
|
void ApplyJournalEntry(JournalEntry const & entry);
|
||||||
void LogDiffInJournal(EditableMapObject const & unedited_emo);
|
void LogDiffInJournal(EditableMapObject const & unedited_emo);
|
||||||
|
private:
|
||||||
|
void ApplyBusinessReplacement(uint32_t new_type);
|
||||||
|
|
||||||
|
public:
|
||||||
/// Check whether langCode can be used as default name.
|
/// Check whether langCode can be used as default name.
|
||||||
static bool CanUseAsDefaultName(int8_t const langCode, std::vector<int8_t> const & nativeMwmLanguages);
|
static bool CanUseAsDefaultName(int8_t const langCode, std::vector<int8_t> const & nativeMwmLanguages);
|
||||||
|
|
||||||
|
|||||||
@@ -3091,6 +3091,13 @@ void Framework::DeleteFeature(FeatureID const & fid)
|
|||||||
UpdatePlacePageInfoForCurrentSelection();
|
UpdatePlacePageInfoForCurrentSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Framework::MarkPlaceAsDisused(osm::EditableMapObject emo)
|
||||||
|
{
|
||||||
|
emo.MarkAsDisused();
|
||||||
|
osm::Editor::Instance().SaveEditedFeature(emo);
|
||||||
|
UpdatePlacePageInfoForCurrentSelection();
|
||||||
|
}
|
||||||
|
|
||||||
osm::NewFeatureCategories Framework::GetEditorCategories() const
|
osm::NewFeatureCategories Framework::GetEditorCategories() const
|
||||||
{
|
{
|
||||||
return osm::Editor::Instance().GetNewFeatureCategories();
|
return osm::Editor::Instance().GetNewFeatureCategories();
|
||||||
|
|||||||
@@ -755,6 +755,7 @@ public:
|
|||||||
bool GetEditableMapObject(FeatureID const & fid, osm::EditableMapObject & emo) const;
|
bool GetEditableMapObject(FeatureID const & fid, osm::EditableMapObject & emo) const;
|
||||||
osm::Editor::SaveResult SaveEditedMapObject(osm::EditableMapObject emo);
|
osm::Editor::SaveResult SaveEditedMapObject(osm::EditableMapObject emo);
|
||||||
void DeleteFeature(FeatureID const & fid);
|
void DeleteFeature(FeatureID const & fid);
|
||||||
|
void MarkPlaceAsDisused(osm::EditableMapObject emo);
|
||||||
osm::NewFeatureCategories GetEditorCategories() const;
|
osm::NewFeatureCategories GetEditorCategories() const;
|
||||||
bool RollBackChanges(FeatureID const & fid);
|
bool RollBackChanges(FeatureID const & fid);
|
||||||
void CreateNote(osm::MapObject const & mapObject, osm::Editor::NoteProblemType const type, std::string const & note);
|
void CreateNote(osm::MapObject const & mapObject, osm::Editor::NoteProblemType const type, std::string const & note);
|
||||||
|
|||||||
Reference in New Issue
Block a user