iOS6 MapKit (MKLocalSearch): How to get Address of a mapItem? - mapkit

iOS6 Apple MapKit
So I understand the code in the link below for the most part.
http://phpadvocate.com/blog/2013/01/ios-6-1-simple-example-using-mklocalsearch/
However, how do I get the address for the mapItem? Seems like the other properties include: placemark, isCurrentLocation, name, phoneNumber, and url.
http://developer.apple.com/library/ios/documentation/MapKit/Reference/MKMapItem_class/MKMapItem_class.pdf
Basically, once the data is fetched, I'd like to display the name of the retail location as the cell.text and the address as cell.detailText.

mapItem.placemark.thoroughfare.copy, // Will return first single line address
mapItem.placemark.locality, // Will return City
mapItem.placemark.administrativeArea //Will return State.
Below are some more:
CLPlacemark | Property Meaning
Thoroughfare | Street address. First line if multiple lines.
subThoroughfare | Street address, second line (e.g., apartment or unit number, box number)
Locality | City
SubLocality | This might contain a neighborhood or landmark name, though it’s often nil
administrativeArea | State, province, territory, or other similar unit
dministrativeArea | County
postalCode | ZIP code
Country | Country
countryCode | Two-digit ISO country code

To correct the "correct answer", the subThoroughfare doesn't contain apartment number or unit number, it is the house number.
Apartment number is in subPremise, which I do not know how to retrieve yet.

Related

Best way to add info/description to my items?

I made a geo game a while back where the player has to guess an item from an image (what I call an item is a SQL row basically) for example the bot sends the flag of the Netherlands, you have to type "Netherlands" to win.
Items can be the flag of a country, a capital city, a french department...
I made an info tab where it would basically give info about an item (ie region, former name, capital city, etc).
What I would like to do is properly save this information. I don't really know if I should store this in files like JSON because I would also like to give stats (Win rate per region, amount of games played per region, etc...).
Also, these elements are not fixed because some items have regions, capital cities or whatever and some don't.
Item examples :
(For a flag
Column
Attribute
ID
1
Name
United Kingdom
Former name
United Kingdom of Great Britain and Northern Ireland
Code
GB
Continent
Europe
Subregion
Northern Europe
Capital city
London
...
(For a U.S. State)
Column
Attribute
ID
1
Name
Arizona
Capital city
Phoenix
Largest city
Phoenix
...
The both solution (Add all as column and json) are not the proper way.
I think the best design is to have a key-value table.
Create Table tableName (ID INT, [Key] SYSNAME, [Value])
And data will look like:
ID
Key
Value
1
Name
Arizona
1
Capital City
Phoenix
1
Largest City
Phoenix
2
Name
United Kingdom
2
Former name
United Kingdom of Great Britain and Northern Ireland
Most valuable benefits: No Extra storage for columns with large amount of rows with NULL value.

How to match phone number prefix to country from phonenumber in SQL

I am trying to extract the country code prefix from a list of numbers, and match them to the region that they belong to. The data might look something like this:
| id | phone_number |
|----|----------------|
| 1 | +27000000000 |
| 2 | +16840000000 |
| 3 | +10000000000 |
| 4 | +27000000000 |
The country codes here are:
American Samoa: +1684
United States and Caribbean: +1
South Africa: +27
And the desired result would be something this:
| country | count |
|-----------------------------|-------|
| South Africa | 2 |
| American Samoa | 1 |
| United States and Caribbean | 1 |
There are some difficulties because
country prefix codes vary from 1 to 4 numbers and even without the country prefix,
phone number length varies from place to place.
I do not have write access to this DB, so adding another column, while probably the best solution, will not work in this use case
This is my current solution:
SELECT
CASE
WHEN SUBSTRING(phone_number,1,5) = '+1684' THEN 'American Samoa'
WHEN SUBSTRING(phone_number,1,5) = '+1264' THEN 'Anguilla'
...
WHEN SUBSTRING(phone_number,1,5) = '+1599' THEN 'Saint Martin'
WHEN SUBSTRING(phone_number,1,4) = '+355' THEN 'Albania'
WHEN SUBSTRING(phone_number,1,4) = '+213' THEN 'Algeria'
...
WHEN SUBSTRING(phone_number,1,4) = '+263' THEN 'Zimbabwe'
WHEN SUBSTRING(phone_number,1,3) = '+93' THEN 'Afghanistan'
WHEN SUBSTRING(phone_number,1,3) = '+54' THEN 'Argentina'
...
WHEN SUBSTRING(phone_number,1,3) = '+58' THEN 'Venezuela'
WHEN SUBSTRING(phone_number,1,3) = '+84' THEN 'Vietnam'
WHEN SUBSTRING(phone_number,1,2) = '+1' THEN 'United States and Caribbean'
WHEN SUBSTRING(phone_number,1,2) = '+7' THEN 'Kazakhstan, Russia'
ELSE 'unknown'
END as country_name,
count(*)
FROM users
GROUP BY country_name
order by count desc
There are ~205 WHEN ... THEN cases. It seems to be very inefficient and times out. I assume this is because it runs the pattern matching on every row. This would need to scale to roughly 10s of millions of rows
Is there a more efficient way to do this?
I am using postgreSQL 9.6.16
In spite of reading the whole table, an index could help here. In order to aggregate the data per country code, the DBMS must sort all rows by country code. Sorting is an expensive operation, especially on large data sets. If you had an index on the country codes, the DBMS would find the codes already pre-sorted in the index and could avoid the work of sorting the data.
You don't have the separate country code in a column, but each phone number starts with the code, so you could index the complete phone number:
create index idx on users (phone_number);
Then you must make it obvious to the DBMS that you are interested in the beginnings of the string, so it will consider using the index. Invoking a function like SUBSTRING on the phone number is likely to make the the DBMS blind to this. Use LIKE instead. According to the docs (https://www.postgresql.org/docs/9.3/indexes-types.html), indexes on strings can be used with LIKE 'something%':
WHEN phone_number LIKE '+1684%' THEN 'American Samoa'
There is no guarantee this will help, but it's worth a try I think. It depends on whether the optimizer sees the advantage of using the pre-sorted phone numbers from the index.

SQL Match City Name Inside Full Address?

How would you list the people from a database that are not from 'London'?
Say the database is:
Cust_id address
1 33 avenue, Liverpool
2 21 street 12345, London
3 469 connection ave, Manchester
I'd like to list the customers that are NOT from London. Here's what I've tried:
select Cust_id from customers where address <> 'London';
Now when I do that, it lists all the customers, regardless of location.
Help would be greatly appericated.
Not ideal but might satisfy your requirements:
select Cust_id from customers
where address NOT LIKE '% London%';
[Note the added space: it assumes you will always precede the city name with a space. '%London%' would match words containing London]
(It might be better if you had a normalised address, i.e. broken into street address, town, city, etc.))
Try this:
select Cust_id from customers where address not like '%London%';
or this:
select Cust_id from customers where not address like '%London%';
Both of these are OK.
For more details on LIKE see e.g. here: SQL LIKE

postgis query for addresses (with osm data)

I want to make queries for addresses to postgis database with data from openstreetmap, check if such address exist in database and if so, get coordinates. Database was filled from .pbf file using osmosis. This is schema for the database http://pastebin.com/Yigjt77f. I have addresses in form of city name, street name and number of street. The most important for me is this table:
CREATE TABLE node_tags (
node_id BIGINT NOT NULL,
k text NOT NULL,
v text NOT NULL
);
k column is in form of tags, one that I'm interested are: addr:housenumber, addr:street, addr:city and v is corresponding value. First I'm searching if name of city matches one in database, than in results set I'm searching for street and than for house number. The problem is that I don't know how to make SQL query that will get this result with asking only once. I can ask first only for city name, get all node_id that match my city and save them in java program, than make queries asking for each found(matching my city) id_number (list from my java program) for the street, and so on. This way is really slow, because asking for more detailed information (city than street than number) I have to make more and more queries and what is more I have to check a lot of addresses. Once I have matching node_id I can easily find coordinates, so that's not a problem.
Example of this table:
node_id | k | v <br>
123 | addr:housenumber | 50
123 | addr:street | Kingsway
123 | addr:city | London
123 | (some other stuff) | .....
100 | addr:housenumber | 121
100 | addr:street | Edmund St
100 | addr:city | London
I hope I explained clearly what is my problem.
This is not as easy as you might think. Addresses in OSM are hierarchically, like in the real world. Not all elements in OSM have a full address attached. Some only have addr:housenumber and simply belong to the nearest street. Some have addr:housenumber and addr:street but no addr:city because they simply belong to the nearest city. Or they are enclosed by a boundary relation which specifies the corresponding city. And instead of addr:housenumber there are sometimes also just address interpolations described by the addr:interpolation key. See the addr key wiki page for more information.
The Karlsruhe Schema page in the OSM wiki explains a lot about addresses in OSM. It also mentions associatedStreet relations which are sometimes used to group house numbers and their corresponding streets.
As you can see a single query in the database probably won't suffice. If you need some inspiration you can take a look at OSM's address search engine Nominatim. But note that Nominatim uses a different data base scheme than the usual one in order to optimize address queries. You can also take a look at one of the many routing applications which all have to do address lookups.

sql create a field from a field

I need to run a query that would pull information from a field that has 2 types of data .
Field is address and has 123 avenue as data and bb#yahoo.com.
I need to make 2 fields one for email and one STaddress from table customer and field address?
anyone can i assis..
its access and vb query
I thought of this
Select customer.address from customer where address like "#"
but still i need to display the the data of address field to 2 different fields...
Here is the query that fetches the two different fields:
select iif(field like '*#*', field, NULL) as email,
iif(field like '*#*, NULL, field) as address
from t
The usage of like in Access is a bit different from other databases.
I would suggest that you create a view with this logic. If you actually want to modify the table, you will have to add columns and populate them with logic like the above.
Based on this question and your duplicate question, I understand your table has a field which includes both the street address and email address and you want to split those into separate fields.
So your table includes this ...
YourField
------------------------------
1234 ave willie haha#yahoo.com
123 avenue bb#yahoo.com
And you want this ...
YourField street_address email_address
------------------------------ --------------- --------------
1234 ave willie haha#yahoo.com 1234 ave willie haha#yahoo.com
123 avenue bb#yahoo.com 123 avenue bb#yahoo.com
If that is correct, you can use the InstrRev() function to determine the position of the last space in YourField. Everything before the last space is the street address; everything after is the email address.
SELECT
y.YourField,
Left(y.YourField, InstrRev(y.YourField, ' ') -1) AS street_address,
Mid(y.YourField, InstrRev(y.YourField, ' ') +1) AS email_address
FROM YourTable AS y;
You may need to add a WHERE clause to ensure the query only tries to evaluate rows which include your expected YourField value patterns.
Try something like this:
select *,
(case locate('#', address) when 0 then null else address) as email,
(case locate('#', address) when 0 then address else null) as street
from table;
You'd probably need to adjust the name of "locate" function - I'm not sure if it is the same in access database.
If you have a street address and then an email address in the same field, and want to split them, then use this.
We'll call your original field Addy, and the new fields Street & Email.
SELECT Left(Addy, InStrRev(Addy, " ", InStr(Addy, "#")) - 1) AS Street, mid(Addy, InStrRev(Addy, " ", InStr(Addy, "#")) + 1) AS Email.
What this does is look for the #, then go backwards and look for the first space. The first function takes every left of that space and calls it Street, while the second function takes everything to the right.
The function is really 3 functions nested together. To really understand what it's doing, I'll dissect it.
I = InStr(Addy, "#")
J = InStrRev(Addy, " ", I)
Street = Left(Addy,J-1)