Merge pull request #3383 from syershov/MAPSME-1281

[booking] The matching function and quality check tools
This commit is contained in:
mpimenov 2016-06-01 14:05:34 +04:00
commit 307aba44f2
9 changed files with 375 additions and 17 deletions

View file

@ -223,6 +223,12 @@ void BookingDataset::BuildFeatures(function<void(OsmElement *)> const & fn) cons
}
}
static double BookingDataset::ScoreByLinearNormDistance(double distance) const
{
distance = my::clamp(distance, 0, kDistanceLimitInMeters);
return 1.0 - distance / kDistanceLimitInMeters;
}
void BookingDataset::LoadHotels(string const & path)
{
m_hotels.clear();
@ -256,12 +262,21 @@ bool BookingDataset::MatchWithBooking(OsmElement const & e) const
if (name.empty())
return false;
// Find 3 nearest values to a point.
auto const indexes = GetNearestHotels(e.lat, e.lon, 3, 150 /* max distance in meters */);
if (indexes.empty())
return false;
// Find |kMaxSelectedElements| nearest values to a point.
auto const bookingIndexes = GetNearestHotels(e.lat, e.lon, kMaxSelectedElements, kDistanceLimitInMeters);
bool matched = false;
for (size_t const j : bookingIndexes)
{
auto const & hotel = GetHotel(j);
double const distanceMeters = ms::DistanceOnEarth(e.lat, e.lon, hotel.lat, hotel.lon);
double score = ScoreByLinearNormDistance(distanceMeters);
matched = score > kOptimalThreshold;
if (matched)
break;
}
bool matched = MatchByName(name, indexes);
return matched;
}

View file

@ -15,6 +15,12 @@ namespace generator
class BookingDataset
{
public:
double static constexpr kDistanceLimitInMeters = 150;
size_t static constexpr kMaxSelectedElements = 3;
// Calculated with tools/python/booking_hotels_quality.py
double static constexpr kOptimalThreshold = 0.709283;
struct Hotel
{
enum class Fields
@ -63,6 +69,8 @@ public:
void BuildFeatures(function<void(OsmElement *)> const & fn) const;
static double ScoreByLinearNormDistance(double distance) const;
protected:
vector<Hotel> m_hotels;

View file

@ -0,0 +1,108 @@
#include "generator/booking_dataset.hpp"
#include "generator/osm_source.hpp"
#include "geometry/distance_on_sphere.hpp"
#include "std/fstream.hpp"
#include "std/iostream.hpp"
#include "std/numeric.hpp"
#include "3party/gflags/src/gflags/gflags.h"
DEFINE_bool(generate_classif, false, "Generate classificator.");
DEFINE_string(osm_file_name, "", "Input .o5m file");
DEFINE_string(booking_data, "", "Path to booking data in .tsv format");
DEFINE_string(sample_data, "", "Sample output path");
DEFINE_uint64(selection_size, 1000, "Selection size");
using namespace generator;
ostream & operator<<(ostream & s, OsmElement const & e)
{
for (auto const & tag : e.Tags())
{
auto t = tag;
replace(t.key.begin(), t.key.end(), '\n', ' ');
replace(t.value.begin(), t.value.end(), '\n', ' ');
s << t.key << "=" << t.value << "\t";
}
return s;
}
int main(int argc, char * argv[])
{
google::SetUsageMessage(
"Takes OSM XML data from stdin and creates"
" data and index files in several passes.");
google::ParseCommandLineFlags(&argc, &argv, true);
LOG_SHORT(LINFO, ("Booking data:", FLAGS_booking_data));
BookingDataset bookingDataset(FLAGS_booking_data);
vector<OsmElement> elements;
LOG_SHORT(LINFO, ("OSM data:", FLAGS_osm_file_name));
{
SourceReader reader =
FLAGS_osm_file_name.empty() ? SourceReader() : SourceReader(FLAGS_osm_file_name);
ProcessOsmElementsFromO5M(reader, [&](OsmElement * e)
{
if (bookingDataset.TourismFilter(*e))
elements.emplace_back(*e);
});
}
LOG_SHORT(LINFO, ("Num of tourism elements:", elements.size()));
vector<size_t> elementIndexes(elements.size());
iota(elementIndexes.begin(), elementIndexes.end(), 0);
// In first implementation, we used random_shufle for reference dataset.
// Next time we are going to replace random_shuffle by shuffle with defined seed.
random_shuffle(elementIndexes.begin(), elementIndexes.end());
if (FLAGS_selection_size < elementIndexes.size())
elementIndexes.resize(FLAGS_selection_size);
stringstream outStream;
for (size_t i : elementIndexes)
{
OsmElement const & e = elements[i];
auto const bookingIndexes = bookingDataset.GetNearestHotels(
e.lat, e.lon, BookingDataset::kMaxSelectedElements, BookingDataset::kDistanceLimitInMeters);
for (size_t const j : bookingIndexes)
{
auto const & hotel = bookingDataset.GetHotel(j);
double const distanceMeters = ms::DistanceOnEarth(e.lat, e.lon, hotel.lat, hotel.lon);
double score = BookingDataset::ScoreByLinearNormDistance(distanceMeters);
bool matched = score > BookingDataset::kOptimalThreshold;
outStream << "# ------------------------------------------" << fixed << setprecision(6)
<< endl;
outStream << (matched ? 'y' : 'n') << " \t" << i << "\t " << j
<< " distance: " << distanceMeters << " score: " << score << endl;
outStream << "# " << e << endl;
outStream << "# " << hotel << endl;
outStream << "# URL: https://www.openstreetmap.org/?mlat=" << hotel.lat
<< "&mlon=" << hotel.lon << "#map=18/" << hotel.lat << "/" << hotel.lon << endl;
}
if (!bookingIndexes.empty())
outStream << endl << endl;
}
if (FLAGS_sample_data.empty())
{
cout << outStream.str();
}
else
{
ofstream file(FLAGS_sample_data);
if (file.is_open())
file << outStream.str();
else
LOG(LERROR, ("Can't output into", FLAGS_sample_data));
}
return 0;
}

View file

@ -12,7 +12,7 @@ UNIT_TEST(Source_To_Element_create_from_xml_test)
SourceReader reader(ss);
vector<OsmElement> elements;
BuildFeaturesFromXML(reader, [&elements](OsmElement * e)
ProcessOsmElementsFromXML(reader, [&elements](OsmElement * e)
{
elements.push_back(*e);
});
@ -27,7 +27,7 @@ UNIT_TEST(Source_To_Element_create_from_o5m_test)
SourceReader reader(ss);
vector<OsmElement> elements;
BuildFeaturesFromO5M(reader, [&elements](OsmElement * e)
ProcessOsmElementsFromO5M(reader, [&elements](OsmElement * e)
{
elements.push_back(*e);
});
@ -42,7 +42,7 @@ UNIT_TEST(Source_To_Element_check_equivalence)
SourceReader readerXML(ss1);
vector<OsmElement> elementsXML;
BuildFeaturesFromXML(readerXML, [&elementsXML](OsmElement * e)
ProcessOsmElementsFromXML(readerXML, [&elementsXML](OsmElement * e)
{
elementsXML.push_back(*e);
});
@ -52,7 +52,7 @@ UNIT_TEST(Source_To_Element_check_equivalence)
SourceReader readerO5M(ss2);
vector<OsmElement> elementsO5M;
BuildFeaturesFromO5M(readerO5M, [&elementsO5M](OsmElement * e)
ProcessOsmElementsFromO5M(readerO5M, [&elementsO5M](OsmElement * e)
{
elementsO5M.push_back(*e);
});

View file

@ -408,7 +408,7 @@ void BuildIntermediateDataFromXML(SourceReader & stream, TCache & cache, TownsDu
ParseXMLSequence(stream, parser);
}
void BuildFeaturesFromXML(SourceReader & stream, function<void(OsmElement *)> processor)
void ProcessOsmElementsFromXML(SourceReader & stream, function<void(OsmElement *)> processor)
{
XMLSource parser([&](OsmElement * e) { processor(e); });
ParseXMLSequence(stream, parser);
@ -431,7 +431,7 @@ void BuildIntermediateDataFromO5M(SourceReader & stream, TCache & cache, TownsDu
}
}
void BuildFeaturesFromO5M(SourceReader & stream, function<void(OsmElement *)> processor)
void ProcessOsmElementsFromO5M(SourceReader & stream, function<void(OsmElement *)> processor)
{
using TType = osm::O5MSource::EntityType;
@ -516,6 +516,8 @@ bool GenerateFeaturesImpl(feature::GenerateInfo & info)
// If info.m_bookingDatafileName is empty then no data will be loaded.
generator::BookingDataset bookingDataset(info.m_bookingDatafileName);
stringstream skippedElements;
// Here we can add new tags to element!!!
auto const fn = [&](OsmElement * e)
{
@ -523,7 +525,10 @@ bool GenerateFeaturesImpl(feature::GenerateInfo & info)
tagAdmixer(e);
if (bookingDataset.BookingFilter(*e))
{
skippedElements << e->id << endl;
return;
}
parser.EmitElement(e);
};
@ -532,10 +537,10 @@ bool GenerateFeaturesImpl(feature::GenerateInfo & info)
switch (info.m_osmFileType)
{
case feature::GenerateInfo::OsmSourceType::XML:
BuildFeaturesFromXML(reader, fn);
ProcessOsmElementsFromXML(reader, fn);
break;
case feature::GenerateInfo::OsmSourceType::O5M:
BuildFeaturesFromO5M(reader, fn);
ProcessOsmElementsFromO5M(reader, fn);
break;
}
@ -545,6 +550,17 @@ bool GenerateFeaturesImpl(feature::GenerateInfo & info)
{
bookingDataset.BuildFeatures([&](OsmElement * e) { parser.EmitElement(e); });
LOG(LINFO, ("Processing booking data from", info.m_bookingDatafileName, "done."));
string skippedElementsPath = info.GetIntermediateFileName("skipped_elements", ".lst");
ofstream file(skippedElementsPath);
if (file.is_open())
{
file << skippedElements.str();
LOG(LINFO, ("Saving skipped elements to", skippedElementsPath, "done."));
}
else
{
LOG(LERROR, ("Can't output into", skippedElementsPath));
}
}
parser.Finish();

View file

@ -35,6 +35,6 @@ public:
bool GenerateFeatures(feature::GenerateInfo & info);
bool GenerateIntermediateData(feature::GenerateInfo & info);
void BuildFeaturesFromO5M(SourceReader & stream, function<void(OsmElement *)> processor);
void BuildFeaturesFromXML(SourceReader & stream, function<void(OsmElement *)> processor);
void ProcessOsmElementsFromO5M(SourceReader & stream, function<void(OsmElement *)> processor);
void ProcessOsmElementsFromXML(SourceReader & stream, function<void(OsmElement *)> processor);

View file

@ -6,6 +6,7 @@
#include <numeric>
using std::accumulate;
using std::iota;
#ifdef DEBUG_NEW
#define new DEBUG_NEW

View file

@ -0,0 +1,88 @@
#!/usr/bin/python
# coding: utf8
from __future__ import print_function
from collections import namedtuple, defaultdict
from datetime import datetime
from sklearn import metrics
import argparse
import base64
import json
import logging
import matplotlib.pyplot as plt
import os
import pickle
import time
import urllib2
# init logging
logging.basicConfig(level=logging.DEBUG, format='[%(asctime)s] %(levelname)s: %(message)s')
def load_binary_list(path):
"""
Loads binary classifier output.
"""
bits = []
with open(path, 'r') as fd:
for line in fd:
if (not line.strip()) or line[0] == '#':
continue
bits.append(1 if line[0] == 'y' else 0)
return bits
def load_score_list(path):
"""
Loads list of matching scores.
"""
scores = []
with open(path, 'r') as fd:
for line in fd:
if (not line.strip()) or line[0] == '#':
continue
scores.append(float(line[line.rfind(':')+2:]))
return scores
def process_options():
parser = argparse.ArgumentParser(description="Download and process booking hotels.")
parser.add_argument("-v", "--verbose", action="store_true", dest="verbose")
parser.add_argument("-q", "--quiet", action="store_false", dest="verbose")
parser.add_argument("--reference_list", dest="reference_list", help="Path to data files")
parser.add_argument("--sample_list", dest="sample_list", help="Name and destination for output file")
parser.add_argument("--show", dest="show", default=False, action="store_true",
help="Show graph for precision and recall")
options = parser.parse_args()
if not options.reference_list or not options.sample_list:
parser.print_help()
exit()
return options
def main():
options = process_options()
reference = load_binary_list(options.reference_list)
sample = load_score_list(options.sample_list)
precision, recall, threshold = metrics.precision_recall_curve(reference, sample)
aa = zip(precision, recall, threshold)
max_by_hmean = max(aa, key=lambda (p, r, t): p*r/(p+r))
print("Optimal threshold: {2} for precision: {0} and recall: {1}".format(*max_by_hmean))
print("AUC: {0}".format(metrics.roc_auc_score(reference, sample)))
if options.show:
plt.plot(recall, precision)
plt.title("Precision/Recall")
plt.ylabel("Precision")
plt.xlabel("Recall")
plt.show()
if __name__ == "__main__":
main()

View file

@ -17,6 +17,23 @@
6726C2231A4C2BBD005EEA39 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 675343E01A3F600D00A0A8C3 /* IOKit.framework */; };
6726C2261A4C2BBD005EEA39 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 675343E21A3F607600A0A8C3 /* Cocoa.framework */; };
6726C2411A4C2D9F005EEA39 /* testingmain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6726C2401A4C2D9F005EEA39 /* testingmain.cpp */; };
673746671CF4641B005E6D1F /* booking_quality_check.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 673746661CF4641B005E6D1F /* booking_quality_check.cpp */; };
673746681CF47A7B005E6D1F /* libgflags.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28CC1B1C7FED001A525C /* libgflags.a */; };
673746691CF47BD9005E6D1F /* libgenerator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28CA1B1C7FED001A525C /* libgenerator.a */; };
6737466A1CF47D82005E6D1F /* libbase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28D71B1C800D001A525C /* libbase.a */; };
6737466B1CF47D82005E6D1F /* libplatform.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28D31B1C8001001A525C /* libplatform.a */; };
6737466C1CF47D82005E6D1F /* libcoding.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28C91B1C7FED001A525C /* libcoding.a */; };
6737466D1CF47D82005E6D1F /* libgeometry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28CB1B1C7FED001A525C /* libgeometry.a */; };
6737466E1CF47D82005E6D1F /* libindexer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28CD1B1C7FED001A525C /* libindexer.a */; };
6737466F1CF47D82005E6D1F /* libexpat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28C71B1C7FC9001A525C /* libexpat.a */; };
673746701CF47E14005E6D1F /* libeditor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 675340891C523054002CF0D9 /* libeditor.a */; };
673746711CF47E14005E6D1F /* librouting.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28D41B1C8001001A525C /* librouting.a */; };
673746721CF47E3D005E6D1F /* libpugixml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6753408A1C523054002CF0D9 /* libpugixml.a */; };
673746731CF47E54005E6D1F /* libjansson.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28ED1B1C80FB001A525C /* libjansson.a */; };
673746741CF47E54005E6D1F /* libtomcrypt.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28DD1B1C8027001A525C /* libtomcrypt.a */; };
673746751CF47E7A005E6D1F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 675343DE1A3F5FE500A0A8C3 /* CoreFoundation.framework */; };
673746761CF47E7F005E6D1F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 675343E01A3F600D00A0A8C3 /* IOKit.framework */; };
673746771CF47E83005E6D1F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 675343E21A3F607600A0A8C3 /* Cocoa.framework */; };
674A28C81B1C7FC9001A525C /* libexpat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28C71B1C7FC9001A525C /* libexpat.a */; };
674A28CE1B1C7FED001A525C /* libcoding.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28C91B1C7FED001A525C /* libcoding.a */; };
674A28CF1B1C7FED001A525C /* libgenerator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674A28CA1B1C7FED001A525C /* libgenerator.a */; };
@ -82,6 +99,15 @@
);
runOnlyForDeploymentPostprocessing = 1;
};
6737465D1CF4639F005E6D1F /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
675341561A3F54D800A0A8C3 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -162,6 +188,8 @@
6726C1EC1A4C28D5005EEA39 /* triangles_tree_coding_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = triangles_tree_coding_test.cpp; sourceTree = "<group>"; };
6726C2351A4C2BBD005EEA39 /* generator_tests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = generator_tests; sourceTree = BUILT_PRODUCTS_DIR; };
6726C2401A4C2D9F005EEA39 /* testingmain.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = testingmain.cpp; path = ../../testing/testingmain.cpp; sourceTree = "<group>"; };
6737465F1CF4639F005E6D1F /* booking_quality_check */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = booking_quality_check; sourceTree = BUILT_PRODUCTS_DIR; };
673746661CF4641B005E6D1F /* booking_quality_check.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = booking_quality_check.cpp; sourceTree = "<group>"; };
674A28C71B1C7FC9001A525C /* libexpat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libexpat.a; path = "../../../omim-xcode-build/Debug/libexpat.a"; sourceTree = "<group>"; };
674A28C91B1C7FED001A525C /* libcoding.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcoding.a; path = "../../../omim-xcode-build/Debug/libcoding.a"; sourceTree = "<group>"; };
674A28CA1B1C7FED001A525C /* libgenerator.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgenerator.a; path = "../../../omim-xcode-build/Debug/libgenerator.a"; sourceTree = "<group>"; };
@ -198,7 +226,6 @@
67AB92C61B73D03500AB5194 /* libmap.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmap.a; path = "../../../omim-xcode-build/Debug/libmap.a"; sourceTree = "<group>"; };
67AB92C81B73D10200AB5194 /* libosrm.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libosrm.a; path = "../../../omim-xcode-build/Debug/libosrm.a"; sourceTree = "<group>"; };
67AB92CA1B73D10B00AB5194 /* libsuccinct.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsuccinct.a; path = "../../../omim-xcode-build/Debug/libsuccinct.a"; sourceTree = "<group>"; };
67AB92CC1B73D15700AB5194 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -230,6 +257,29 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
6737465C1CF4639F005E6D1F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
673746771CF47E83005E6D1F /* Cocoa.framework in Frameworks */,
673746701CF47E14005E6D1F /* libeditor.a in Frameworks */,
6737466B1CF47D82005E6D1F /* libplatform.a in Frameworks */,
673746741CF47E54005E6D1F /* libtomcrypt.a in Frameworks */,
673746711CF47E14005E6D1F /* librouting.a in Frameworks */,
6737466D1CF47D82005E6D1F /* libgeometry.a in Frameworks */,
6737466F1CF47D82005E6D1F /* libexpat.a in Frameworks */,
673746681CF47A7B005E6D1F /* libgflags.a in Frameworks */,
673746731CF47E54005E6D1F /* libjansson.a in Frameworks */,
673746761CF47E7F005E6D1F /* IOKit.framework in Frameworks */,
673746691CF47BD9005E6D1F /* libgenerator.a in Frameworks */,
6737466E1CF47D82005E6D1F /* libindexer.a in Frameworks */,
673746751CF47E7A005E6D1F /* CoreFoundation.framework in Frameworks */,
673746721CF47E3D005E6D1F /* libpugixml.a in Frameworks */,
6737466C1CF47D82005E6D1F /* libcoding.a in Frameworks */,
6737466A1CF47D82005E6D1F /* libbase.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
675341551A3F54D800A0A8C3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -352,10 +402,20 @@
path = ../../generator/generator_tests;
sourceTree = "<group>";
};
6737465A1CF46324005E6D1F /* booking_quality_check */ = {
isa = PBXGroup;
children = (
673746661CF4641B005E6D1F /* booking_quality_check.cpp */,
);
name = booking_quality_check;
path = ../../generator/booking_quality_check;
sourceTree = "<group>";
};
6753414F1A3F54D800A0A8C3 = {
isa = PBXGroup;
children = (
670D05AD1B0E08260013A7AC /* defaults.xcconfig */,
6737465A1CF46324005E6D1F /* booking_quality_check */,
670B84C41A9F73AB00CE4492 /* std */,
6753453F1A3F6FA600A0A8C3 /* libs */,
6726C1D71A4C27A5005EEA39 /* generator_tests */,
@ -369,6 +429,7 @@
children = (
675341581A3F54D800A0A8C3 /* generator_tool */,
6726C2351A4C2BBD005EEA39 /* generator_tests */,
6737465F1CF4639F005E6D1F /* booking_quality_check */,
);
name = Products;
sourceTree = "<group>";
@ -411,7 +472,6 @@
674A28CC1B1C7FED001A525C /* libgflags.a */,
674A28CD1B1C7FED001A525C /* libindexer.a */,
674A28C71B1C7FC9001A525C /* libexpat.a */,
67AB92CC1B73D15700AB5194 /* Foundation.framework */,
675343E21A3F607600A0A8C3 /* Cocoa.framework */,
675343E01A3F600D00A0A8C3 /* IOKit.framework */,
675343DE1A3F5FE500A0A8C3 /* CoreFoundation.framework */,
@ -439,6 +499,23 @@
productReference = 6726C2351A4C2BBD005EEA39 /* generator_tests */;
productType = "com.apple.product-type.tool";
};
6737465E1CF4639F005E6D1F /* booking_quality_check */ = {
isa = PBXNativeTarget;
buildConfigurationList = 673746631CF4639F005E6D1F /* Build configuration list for PBXNativeTarget "booking_quality_check" */;
buildPhases = (
6737465B1CF4639F005E6D1F /* Sources */,
6737465C1CF4639F005E6D1F /* Frameworks */,
6737465D1CF4639F005E6D1F /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = booking_quality_check;
productName = booking_quality_check;
productReference = 6737465F1CF4639F005E6D1F /* booking_quality_check */;
productType = "com.apple.product-type.tool";
};
675341571A3F54D800A0A8C3 /* generator_tool */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6753415F1A3F54D800A0A8C3 /* Build configuration list for PBXNativeTarget "generator_tool" */;
@ -465,6 +542,9 @@
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = maps.me;
TargetAttributes = {
6737465E1CF4639F005E6D1F = {
CreatedOnToolsVersion = 7.3.1;
};
675341571A3F54D800A0A8C3 = {
CreatedOnToolsVersion = 6.1;
};
@ -484,6 +564,7 @@
targets = (
675341571A3F54D800A0A8C3 /* generator_tool */,
6726C21C1A4C2BBD005EEA39 /* generator_tests */,
6737465E1CF4639F005E6D1F /* booking_quality_check */,
);
};
/* End PBXProject section */
@ -510,6 +591,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
6737465B1CF4639F005E6D1F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
673746671CF4641B005E6D1F /* booking_quality_check.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
675341541A3F54D800A0A8C3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -554,6 +643,30 @@
};
name = Release;
};
673746641CF4639F005E6D1F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CODE_SIGN_IDENTITY = "-";
DEBUG_INFORMATION_FORMAT = dwarf;
GCC_NO_COMMON_BLOCKS = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
673746651CF4639F005E6D1F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
GCC_NO_COMMON_BLOCKS = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
6753415D1A3F54D800A0A8C3 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 670D05AD1B0E08260013A7AC /* defaults.xcconfig */;
@ -689,6 +802,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
673746631CF4639F005E6D1F /* Build configuration list for PBXNativeTarget "booking_quality_check" */ = {
isa = XCConfigurationList;
buildConfigurations = (
673746641CF4639F005E6D1F /* Debug */,
673746651CF4639F005E6D1F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
675341531A3F54D800A0A8C3 /* Build configuration list for PBXProject "generator_tool" */ = {
isa = XCConfigurationList;
buildConfigurations = (